diff --git a/.bzrignore b/.bzrignore index 37ab760e19..9aa0bfae5c 100644 --- a/.bzrignore +++ b/.bzrignore @@ -23,3 +23,9 @@ installer/windows/calibre/build.log src/calibre/translations/.errors src/calibre/plugins/* src/calibre/gui2/pictureflow/.build +src/cssutils/.svn/ +src/cssutils/_todo/ +src/cssutils/scripts/ +src/cssutils/css/.svn/ +src/cssutils/stylesheets/.svn/ +src/odf/.svn diff --git a/installer/linux/freeze.py b/installer/linux/freeze.py index f32286092a..c063fb852a 100644 --- a/installer/linux/freeze.py +++ b/installer/linux/freeze.py @@ -22,6 +22,9 @@ LIBZ = '/lib/libz.so.1' LIBBZ2 = '/lib/libbz2.so.1' LIBUSB = '/usr/lib/libusb.so' LIBPOPPLER = '/usr/lib/libpoppler.so.3' +LIBXML2 = '/usr/lib/libxml2.so.2' +LIBXSLT = '/usr/lib/libxslt.so.1' +LIBEXSLT = '/usr/lib/libexslt.so.0' CALIBRESRC = os.path.join(CALIBREPREFIX, 'src') @@ -121,7 +124,7 @@ binaries += [('pdftohtml', PDFTOHTML, 'BINARY'), print 'Adding external libraries...' binaries += [ (os.path.basename(x), x, 'BINARY') for x in (SQLITE, DBUS, - LIBMNG, LIBZ, LIBBZ2, LIBUSB, LIBPOPPLER)] + LIBMNG, LIBZ, LIBBZ2, LIBUSB, LIBPOPPLER, LIBXML2, LIBXSLT, LIBEXSLT)] qt = [] diff --git a/installer/osx/freeze.py b/installer/osx/freeze.py index a57b3ce375..f40c280570 100644 --- a/installer/osx/freeze.py +++ b/installer/osx/freeze.py @@ -150,9 +150,9 @@ _check_symlinks_prescript() if not match: print dep raise Exception('Unknown Qt dependency') - module = match.group(1) + module = match.group(1) newpath = fp + '%s.framework/Versions/Current/%s'%(module, module) - cmd = ' '.join(['/usr/bin/install_name_tool', '-change', dep, newpath, path]) + cmd = ' '.join(['/usr/bin/install_name_tool', '-change', dep, newpath, path]) subprocess.check_call(cmd, shell=True) @@ -220,7 +220,7 @@ _check_symlinks_prescript() def run(self): py2app.run(self) - resource_dir = os.path.join(self.dist_dir, + resource_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Resources') frameworks_dir = os.path.join(os.path.dirname(resource_dir), 'Frameworks') all_scripts = scripts['console'] + scripts['gui'] @@ -235,7 +235,7 @@ _check_symlinks_prescript() path = os.path.join(loader_path, name) print 'Creating loader:', path f = open(path, 'w') - f.write(BuildAPP.LOADER_TEMPLATE % dict(module=module, + f.write(BuildAPP.LOADER_TEMPLATE % dict(module=module, function=function)) f.close() os.chmod(path, stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH|stat.S_IREAD\ @@ -301,6 +301,10 @@ sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), ' def main(): sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) sys.argv[1:2] = ['py2app'] + d = os.path.dirname + icon = os.path.abspath('icons/library.icns') + if not os.access(icon, os.R_OK): + raise Exception('No icon at '+icon) setup( name = APPNAME, app = [scripts['gui'][0]], @@ -310,15 +314,16 @@ def main(): 'optimize' : 2, 'dist_dir' : 'build/py2app', 'argv_emulation' : True, - 'iconfile' : 'icons/library.icns', + 'iconfile' : icon, 'frameworks': ['libusb.dylib', 'libunrar.dylib'], 'includes' : ['sip', 'pkg_resources', 'PyQt4.QtXml', - 'PyQt4.QtSvg', 'PyQt4.QtWebKit', + 'PyQt4.QtSvg', 'PyQt4.QtWebKit', 'commands', 'mechanize', 'ClientForm', 'usbobserver', 'genshi', 'calibre.web.feeds.recipes.*', 'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*', - 'keyword', 'codeop', 'pydoc', 'readline'], - 'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'], + 'keyword', 'codeop', 'pydoc', 'readline', + 'BeautifulSoup'], + 'packages' : ['PIL', 'Authorization', 'lxml'], 'excludes' : ['IPython'], 'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.''' ''' Visit http://calibre.kovidgoyal.net for details.''', diff --git a/installer/windows/build_installer.py b/installer/windows/build_installer.py index 949ef2c190..7119d92383 100644 --- a/installer/windows/build_installer.py +++ b/installer/windows/build_installer.py @@ -5,9 +5,11 @@ __docformat__ = 'restructuredtext en' ''' ''' -import sys, time, subprocess, os +import sys, time, subprocess, os, re from calibre import __appname__, __version__ +sv = re.sub(r'[a-z]\d+', '', __version__) + cmdline = [ '/usr/local/installjammer/installjammer', '--build-dir', '/tmp/calibre-installjammer', @@ -18,10 +20,10 @@ cmdline = [ '-DPackageDescription', '%s is an e-book library manager. It can view, convert and catalog e-books in most of the major e-book formats. It can also talk to a few e-book reader devices. It can go out to the internet and fetch metadata for your books. It can download newspapers and convert them into e-books for convenient reading.'%__appname__, '-DPackageSummary', '%s: E-book library management'%__appname__, '-DVersion', __version__, - '-DInstallVersion', __version__ + '.0', + '-DInstallVersion', sv + '.0', '-DLicense', open(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'LICENSE')).read().replace('\n', '\r\n'), '--output-dir', os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'dist'), - '--platform', 'Windows', + '--platform', 'Windows', ] def run_install_jammer(installer_name='<%AppName%>-<%Version%><%Ext%>', build_for_release=True): @@ -43,4 +45,4 @@ def main(args=sys.argv): return 0 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/installer/windows/calibre/calibre.mpi b/installer/windows/calibre/calibre.mpi index 5d70665c2b..f4564c9d4c 100644 --- a/installer/windows/calibre/calibre.mpi +++ b/installer/windows/calibre/calibre.mpi @@ -207,289 +207,7 @@ test } FileGroup ::BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows TarArchive ZipArchive} -name {Program Files} -parent FileGroups -File ::6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -filemethod {Always overwrite files} -type dir -directory <%InstallDir%> -name /home/kovid/work/calibre/build/py2exe -parent BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 -File ::B444456B-BA8D-A058-8C9B-AAC2BBB1560D -type dir -name bin -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D9A3AF75-5939-CB51-9F33-5A048911103E -type dir -name etc -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A628E495-239B-DAF4-D858-BCE36CB41E6E -type dir -name imageformats -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0A533DB2-D494-A9ED-1334-DECC357BD426 -type dir -name codecs -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0F47A44E-E347-1CD4-E89F-37B447C4A270 -type dir -name driver -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A146565C-D163-7F68-7C70-A6A336B32526 -type dir -name iconengines -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3245B06C-1C22-1A8A-5710-6D36651AAA70 -name etree.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B49A5610-13F6-FB5D-0673-DB47C6BB385D -name rtf-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CE4F2A21-12CC-2B9A-6D48-6A0FEA7C9D13 -name _compiled_base.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D6C46340-8335-7FC4-A027-D701DF1B70AB -name pdf2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::53F2B07D-8F92-2328-C55E-5F7F0E63D5DB -name opf-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::63A13E6F-CF99-4D85-2F82-5DFBBB7D8180 -name sqlite3.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B69EBBDA-04FA-A67F-E3ED-3C2E7D761B92 -name _sqlite3.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::24CC4E53-95EB-A527-21C3-B8166080D181 -name lrs2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::99B750DB-EC00-5521-E93E-7FABEA416B0C -name lit2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D8FC08E6-B361-307C-8F62-953A739B2F40 -name txt2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3FCD0C96-DC3A-EC73-7E3A-46A02CE631B0 -name web2disk.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::71F6F80A-0F8E-A96E-CA1B-974F928A0D9B -name calibre-parallel.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EBC815EE-7438-6588-97F9-FBFC39715044 -name html2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AB47ED69-BD17-198D-DE41-0AF44257480F -name LICENSE -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::10537419-4DBF-EE7D-6561-6B0DD6875C47 -name lapack_lite.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8CF0C9F4-3813-7EDE-139F-D78C6FC38694 -name feeds2disk.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::95B4ACBF-CCB7-421E-8956-3C96D6D85DE4 -name calibre.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4B78188A-11BC-E7DA-8583-C690270FDD8B -name web2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8CA63124-E326-1CC2-9B86-C118157ED034 -name QtNetwork4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::431AD2DB-AD8C-4AEB-709C-E1CB8382F8FA -name win32ui.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B145A772-C20C-A6F2-E872-ACC229FFE1C7 -name fb2-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::168973D9-DEE6-7307-9A2E-746EB9456311 -name txt2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BD39D6F0-5125-F3A3-043F-E8FD1C87A823 -name isbndb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6C294A11-52D4-C567-64F7-1DCF21AB06D7 -name epub2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A9BB9531-5BC4-92C1-F614-B84B93F8698F -name pywintypes25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AA725BD8-5FFA-B426-733F-5A1264A30DA2 -name Qt.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B48D9BFD-326D-1C92-4D94-C17F9ACD9207 -name epub2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9104E2C3-8E0D-8275-59EB-6B5E57C7F7C1 -name isbndb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EAE07E71-7B94-DE2F-4A30-4DAF1ADDB591 -name any2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4140B65A-A7F4-0CD2-4613-BED2E87DA01B -name library.zip -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F59AC283-F006-F856-3EA4-694FE4DD4A88 -name unicodedata.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::479B1590-634A-1847-54E9-EF29C239E8E7 -name win32api.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9E7341CF-0A6A-8F36-9B87-BF50C7C825AA -name libfontconfig-1.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::223E6E1F-F83C-1144-9952-98ED4E80F38C -name QtSvg.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A0C13AC8-184A-2F9A-FCD5-D6DA18A7200D -name win32pdh.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::153509C0-E955-D07B-4A7E-0AD74877F530 -name lrs2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::2C03CD3B-6A0E-D31D-FB58-91E48B96E3B1 -name fftpack_lite.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CFA05433-447F-F504-F050-D6B6966D6A74 -name win32clipboard.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::931DA8AF-4252-E09A-BBCD-9591BBACC7FA -name pdfreflow.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C42D8FFA-561F-552E-78DD-A3E441F630CA -name sip.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E1C0697F-BA9B-17AA-3581-079553DCDCAF -name pdfreflow.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9E2D6AAA-3606-82C2-9074-F51017624305 -name pdf-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A665DBDD-BE19-0818-3F30-FA4924AC811F -name rtf-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::2AABAB06-38EF-6F8C-3675-575D8B044E0C -name calibredb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A7EA318A-0542-FBB8-5C93-A39B364A51D9 -name epub-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4CD878C5-1487-1FFD-99A1-EDFC90892F0A -name win32security.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::ADFDF202-EED8-0319-0D69-DF1C44AE465B -name librarything.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0E83E956-FF8D-27AB-9BE9-A24C57F8886A -name pythoncom25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F8DAAE4E-9BF0-F75A-78BD-81E0F4BD1F99 -name epub-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E2982BD3-D0BB-70B4-0BF8-18B2B68C9918 -name QtWebKit4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::73F6E879-EF13-E4D2-D66D-C4A50D5B7A68 -name freetype6.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::47B3352F-C480-8704-0D8D-7CF0FE1D1E8F -name QtCore.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::DDAB10F5-6B92-D2E0-F192-441694C26EB0 -name fb22lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8995CD27-3E9E-8689-5B49-E965E7E52D9A -name pyexpat.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E081A898-F163-D9F4-11E2-C691636BA702 -name calibre-debug.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::801BE53F-D9E4-CA5A-0702-DAF30B96CC04 -name select.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::215B915B-F0FE-C029-C022-24CE35D4A5C1 -name pdf-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D13FB9B3-0A36-B7CA-CA0B-3EF7376A2943 -name feeds2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5404250A-4A38-AE68-7EE1-96947457D92D -name _imagingmath.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::82E7B1F5-0866-8B48-453B-0F7C0A978141 -name QtGui4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B1711D23-A1F1-5660-F7E7-0F30539B7513 -name markdown-calibre.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AEA3C386-69EF-7BF9-44AC-86CA6B303366 -name lrf-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F4B61311-9341-EEB0-92D6-1756B1923358 -name _hashlib.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AFD6F6A1-BD1D-2755-0F72-F5558E5C4C3F -name feeds2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C68EDFE9-EF12-E041-8FF4-240CDC7E23D0 -name libexpat.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C22C6509-C1A2-E883-A675-A97E063FBE73 -name calibre-fontconfig.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::33A4D1AC-78C9-AD8F-BE8E-8136EF0AA299 -name fb22lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E108A8AD-174E-0A51-2C2B-F5A5BB07E0F5 -name unrar.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BA5B6556-608D-2844-4151-25BCA476153B -name mobi2oeb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::53A8A015-111B-957E-6702-3E3A44E61521 -name pdf2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8B8A372C-1473-880E-BBD9-D82DE09F9CCC -name QtGui.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0DF5DAF8-1B14-9D00-30A6-882DAFB107EE -name any2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D75E742F-EF44-769A-EBEF-1EC81B1CCCA7 -name markdown-calibre.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4B02260C-E90F-7B9E-5831-A5F881483BCB -name lit2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::942A727E-E6EE-FE2A-6720-FDB19B8029AA -name calibre-debug.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A61FDA7B-009F-C397-D7F5-E39DC30F14F2 -name prs500.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5324C64E-8774-E051-91EE-CD10289346C7 -name QtXml4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C75049A3-5ADA-664D-8708-133B879C4D3E -name rtf2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A95D56FB-74E0-5A49-ACAE-29F99B4848C0 -name pdftohtml.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::1F00E5E9-7298-E356-0294-CCE7EEE92D22 -name opf-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E5E3FC49-D699-001C-5C97-724CD74FA013 -name web2disk.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0B4D16CB-03A7-36A8-F507-FA6E09DFC303 -name rtf2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F2FEFC47-D830-1A6E-473E-156B3C7C7707 -name QtWebKit.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CDD6643D-5510-EEE5-95F2-D610F8B17801 -name lrfviewer.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9BF1A1FD-61FA-B173-135B-F8CC6AF85ADC -name lrfviewer.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0D47D92A-B91F-76AF-CF1F-81FF655A3E6E -name mobi2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EFB240F8-2D21-655E-6086-764B1ADBD3DB -name lit-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::27D31189-89C1-8B44-70A7-5DB3C2693761 -name umath.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::768C94EF-7C5E-88C9-9513-0ACB7DF63B54 -name _ssl.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D22ADBFF-B91B-4668-400C-F5FCC8ECD23E -name multiarray.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::DD83F9CC-D1CA-F525-64A4-75F5788292B5 -name w9xpopen.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7ED462B5-9B9B-5476-5D91-16AA65FD08C2 -name _sort.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::2132131C-549D-8E7E-AD2D-DEEBECEA8441 -name QtNetwork.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EBAFE980-DF41-5535-5934-1CEA5F4489E8 -name prs500.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E1C90FD6-DE05-2BFC-3B69-586DC4F169F3 -name win32wnet.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AA00495C-C441-F486-B0C0-A3BACB4A2551 -name mtrand.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::31CEC572-AA14-134B-1A4A-FCD9A74DF2FB -name lrf2lrs.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C30F4910-D164-FEA3-4D53-8A559250C071 -name feeds2disk.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E34D773E-A263-F166-3771-59D87FBBF2B8 -name mobi2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A4261177-EB5E-5DD7-2818-4A70C10C5FB7 -name lrf-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B3B72A4E-8B11-2352-A591-0C43E52A2329 -name fb2-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::99EE1D50-3EA6-C2C0-130A-0B830763BC99 -name calibre-fontconfig.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::068F9CD2-4429-9BDC-33E2-417F7A89DF46 -name win32file.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0B892D2B-69B9-A0EF-4CDE-DC13F50EE47A -name lrf2html.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::56F70DCF-A20E-985F-B754-498323515A88 -name lit-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::642F88FB-A6AF-65BA-2D3F-6DFFC51E962F -name MSVCR71.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8D888F32-B960-6FAE-16D1-207449570FD9 -name web2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::086AC033-B68D-0CF2-4317-0EA0D6A13202 -name win32process.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B1DDA977-5BAF-FA72-5A94-886F142D6AE8 -name librarything.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::00220302-54D5-8D81-4DD1-D5F05F36F5C5 -name lrf2html.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C8FC6F5A-7B18-6760-2843-600214FD9C00 -name calibredb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9AE97139-D6D6-CA2C-70DF-91F97F6C8E66 -name _win32sysloader.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::74B69813-5F2F-4096-6940-EED8EAB7E5C8 -name pdftohtml.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::15FE9B66-6A50-987C-6D0A-FAC4FB65D085 -name QtCore4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::91513702-1C71-C2CA-D686-B66501E3E150 -name lrf2lrs.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0F6E5A2A-8D26-31C5-7075-8621CEE7472F -name python25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::50892EC8-2ED5-92E0-5136-28FE9E6F9501 -name _ctypes.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::40C5FFA9-C3FD-2E0A-E25D-F2AA4C2CD672 -name QtSvg4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9ECEF6F4-E95D-3F1A-6400-8726EBE14A6B -name win32event.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6C60B310-E979-5950-4316-B19333F266D8 -name _imagingft.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::23FC9D7B-EC4D-1FB5-1E4D-8AA052A4790B -name html2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B0DBCC9A-8FE2-D917-4FE0-B6D05971F8E8 -name calibre-parallel.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6A287FDE-AB84-041E-886A-923F1D4EADA7 -name _dotblas.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7CDDA16F-629B-5F03-EA19-2508B9C00942 -name win32pipe.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::24A8B830-B46D-207C-6A91-B5E6856E99A4 -name _imaging.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::95782943-BCB9-9A8B-4DB8-1186D35F84E7 -name mingwm10.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::058A6811-F130-999C-B46A-FA86915CDA4E -name calibre.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BEAEEC0C-8321-922D-A113-A2E03C94DC7C -name scalarmath.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::ACE1537B-B234-3C90-759A-8947A7AADC77 -name mobi2oeb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::92701E8F-1D91-A796-C899-2A266029F61D -name _socket.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::45BD27B5-B910-7633-C827-37E82E89C27C -name w9xpopen.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::45C27909-D761-787F-84B2-66596E5C4E99 -name bz2.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -type dir -name plugins -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::71930E14-A27B-C23C-8D94-C7E97ADB8723 -name pictureflow.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -File ::293E6ABE-17C9-5E53-1B44-C27029C8C061 -name winutil.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -File ::A5737158-18DF-7F20-2BDF-2DF615663891 -name lzx.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -File ::CA9E098C-2931-9781-1303-213C242F9A5E -name lit2oeb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::16B5A447-066C-C93E-F63D-8BC0D57CA544 -name lit2oeb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::ABF342D2-82A9-2A20-BA97-54AD5BAF1A2A -name IM_MOD_RL_sfw_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3877E295-C7EB-DF63-DA91-B9E2F9D8035A -name comic2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F47345A3-6CE0-4F5B-9CAE-3F4A18D4AA5A -name IM_MOD_RL_rle_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3A211C93-1B8B-A8AA-E240-A3287974DAB4 -name IM_MOD_RL_tiff_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F24F3123-05A3-B452-D12B-CE6C126501B1 -name CORE_RL_libxml_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D7034E85-2733-DB61-DB49-C34B767B4B45 -name IM_MOD_RL_sun_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::21C1F4D3-487E-5FFF-C8CE-8E5FE779A786 -name IM_MOD_RL_msl_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::01EC7979-C9CB-696C-E8B3-F5945E1115BB -name IM_MOD_RL_jp2_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0F86B693-D83A-DB03-8641-219FE766D980 -name CORE_RL_ttf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::DDCAEB76-7AC4-CA1A-0742-34B556592D2A -name IM_MOD_RL_exr_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4D274537-6B6D-63F2-2615-E0CD279880A3 -name CORE_RL_Magick++_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A87CE00E-9F87-DBE3-DDA5-FC68D6D0731E -name IM_MOD_RL_dib_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9114D530-B73B-CC7C-F6A6-655B7271AB35 -name IM_MOD_RL_preview_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::31EE0880-F1C8-94D6-4EDC-B09A576E0908 -name CORE_RL_magick_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BEA2B769-1A54-4398-E8B4-5BE15637B705 -name IM_MOD_RL_svg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7E300AD4-7C03-5835-0DD6-E9FA8737585A -name IM_MOD_RL_mpeg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5E9901D8-BBB7-A17C-5A04-837C0ADF8CAE -name IM_MOD_RL_clipboard_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F13497D2-87C0-243D-916A-0A160F1A1896 -name IM_MOD_RL_png_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::DBD1CF95-1B01-9F5C-66D9-C7B4E1B44CC7 -name CORE_RL_bzlib_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::149C038D-9CD6-20C5-49C3-FC6948D0709D -name IM_MOD_RL_wmf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F77F5E54-1D54-F7D3-9520-BB1811C11AA6 -name IM_MOD_RL_txt_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3545B38D-1BDF-B355-F779-4D83F292E2B6 -name IM_MOD_RL_viff_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6E33F2FD-17BB-F096-4551-0E3B22924A4D -name IM_MOD_RL_ps2_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F4C810FF-4291-4491-0FA2-CFAD0BA690A9 -name type.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::02A3CD7D-743C-FAA8-9C20-3E8E59B8C2C2 -name IM_MOD_RL_ps3_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::697020D6-C5DA-A7DC-9454-1F9523D7748D -name IM_MOD_RL_dot_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E9D0609E-2D12-A8C0-9B47-D09CACB4A3AF -name IM_MOD_RL_xwd_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F237A6C8-4037-B9E5-8D65-29A5A69CADFE -name IM_MOD_RL_fits_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BDB45C50-E57A-357D-1D5A-392036227E6B -name IM_MOD_RL_histogram_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5A6DBEB5-CD8A-4109-A04C-EF0436BC1CDC -name mfc71.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::FCC2A44D-D2F9-74DC-0C27-86F094E2C3E9 -name IM_MOD_RL_pnm_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8E71473E-34AE-B7A3-B506-8A6AA622DAD7 -name IM_MOD_RL_ipl_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B680E84A-BA1C-5EA2-902E-095DD22A48F2 -name msvcp71.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6AF09D1D-8889-8A87-9FD4-1471DBB1354C -name IM_MOD_RL_rgb_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::941B86E2-428A-3F4A-EB34-CBDBDDAD648C -name IM_MOD_RL_xbm_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::1613269D-8A63-C843-E862-9B80CC17E60F -name IM_MOD_RL_otb_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::334E3925-703D-DDCA-A079-C53DB06AA069 -name IM_MOD_RL_avi_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::23549B03-F856-3B90-C9C5-3B64A5910C7B -name CORE_RL_lcms_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::0E3F5727-D99A-44CD-35E0-4FDFBB95FCBC -name IM_MOD_RL_xpm_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::955B5799-4DB3-F422-589A-CDC20A82B6CB -name IM_MOD_RL_xcf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D3AB494C-3218-0137-4399-3FB1662C05D3 -name IM_MOD_RL_emf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::1DEF5AF0-2376-539B-2A61-35B6ADC2F4BA -name log.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D472B449-3644-C538-30EF-EC42E3B84C43 -name IM_MOD_RL_mtv_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8B4E61F1-8FC2-7E65-4B94-3F19100DF58B -name CORE_RL_tiff_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B747FE2A-0054-6815-40D0-74F89FC8C757 -name IM_MOD_RL_dps_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8B1660CC-7A97-96A2-1280-34554028CB9F -name IM_MOD_RL_dcm_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::21B7EBEC-30C8-F2E8-9D73-E4E6965EA856 -name locale.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::85087BFC-42D6-C583-586E-19CAD45E6A61 -name CORE_RL_wand_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BE24EB64-E7BB-0E63-256E-DEDC2BBF1C2B -name IM_MOD_RL_ttf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7693E752-1A81-F6F3-C55D-9E8D94D6E4DC -name IM_MOD_RL_dpx_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A1451D28-A06B-3F03-4DCA-884729C5A030 -name IM_MOD_RL_jpeg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3F0D8F7A-906F-8CAE-84D7-E3480A09D39D -name IM_MOD_RL_fax_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CA8F1852-F5C1-86E8-31B9-8B1EFE837ADB -name IM_MOD_RL_avs_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::72370AAC-67CF-F570-2AA2-658E4C81C859 -name IM_MOD_RL_mvg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A8265A1E-E9B5-A38F-9ACF-99669CAE1E9F -name IM_MOD_RL_tga_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A8A9A383-0364-515F-C1D8-F82C274D652B -name configure.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A2167661-AF2B-E15E-60DA-715F47E5AA30 -name IM_MOD_RL_uil_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7608E2FF-1BF6-E18A-A884-244794BDA01B -name IM_MOD_RL_cut_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::772CA344-5EFD-78A0-3542-777F12356C8D -name Xext.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::37F8D85E-4EE9-80E5-A4A2-8F30444AD5CC -name IM_MOD_RL_scr_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::973011B9-D193-6D64-D4EB-D82B0C730379 -name IM_MOD_RL_map_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9B9F088C-A20A-0C19-EF7D-52908A020D36 -name thresholds.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::831AAF1C-7CBE-CAD3-79A8-7430E8DE484E -name IM_MOD_RL_thumbnail_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::85236603-D71F-359C-B235-98C77809DDF1 -name IM_MOD_RL_mpc_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::94300805-117F-8337-A9BF-41E10D8AB437 -name IM_MOD_RL_cmyk_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::618A299D-4A28-E37A-D4BF-9209B594FAAF -name IM_MOD_RL_pcd_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9F6572D8-6BE6-290B-D4A7-A0D4E4DBAC23 -name IM_MOD_RL_sct_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::942E63AC-F579-0D17-FF56-E2C8CC5DECA3 -name IM_MOD_RL_pict_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F68DE3F9-742C-D8EE-B2FC-FF9B37EED8F3 -name IM_MOD_RL_gradient_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C460E29B-38EE-6FC0-757B-69563EFC3225 -name IM_MOD_RL_icon_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AE00BD3D-734C-78F6-9078-C04749F4652A -name X11.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B70ED455-A480-56E3-3BDE-E06CDDB62C04 -name IM_MOD_RL_jbig_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CFFC9A5D-2902-FD37-DBD1-6800C7C0C1AE -name magic.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::32DA3775-410C-0391-7ADB-B58028CC04E2 -name IM_MOD_RL_mat_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AB64F079-1F8D-BE3A-731B-4B20ABD20289 -name IM_MOD_RL_meta_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5A7F49E9-119A-FD9B-8186-0BE6B9DCF210 -name IM_MOD_RL_gray_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D92B4157-F307-64A4-9AA5-C5AA1F138E1B -name IM_MOD_RL_pwp_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BA631BF0-CB17-D0EC-FAA9-D7B426457DD3 -name IM_MOD_RL_fpx_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9EA95108-72D5-13B5-2BD4-87CECED9B367 -name IM_MOD_RL_pcl_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::3111AC7E-2387-AD7D-253F-979195AC4EA1 -name english.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::14C1E910-6F5D-9540-7430-6B0B92311EB2 -name IM_MOD_RL_wpg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5D7050F4-177A-03A2-3DD1-A7DFC968E4ED -name IM_MOD_RL_pdb_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5BACE29D-FAFD-E673-16A9-D22DCE6E0655 -name IM_MOD_RL_label_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::25F84452-26F7-4305-B405-B1D0C7D072D2 -name IM_MOD_RL_clip_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::807E6FF7-2D61-F308-BA2A-BD07A213078A -name IM_MOD_RL_pix_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::1A951976-DBCC-9FAE-190C-B24BBA38A97A -name colors.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::8608BB2C-6CDE-BBE7-39C6-DF83625D5BFB -name IM_MOD_RL_cin_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::CBE1DFDA-7E32-759F-346E-DD469B1CE1F0 -name IM_MOD_RL_bmp_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7AD432A3-5146-4966-8C8E-85ACDCC8CA7A -name IM_MOD_RL_raw_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9DC22033-0F40-26CC-9E09-959738F62855 -name IM_MOD_RL_cip_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A8C777EC-AEAA-6B3F-22A6-CEC28A2E5058 -name IM_MOD_RL_pdf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::ACA1A829-27AE-EFE7-4EDD-01D050A2E0A6 -name analyze.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::C883300E-0C2A-EAF6-D72E-81E8B99535E1 -name IM_MOD_RL_mpr_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A223D40F-EFC5-31E3-8E33-B90984080A3E -name CORE_RL_jpeg_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::DE197248-9758-A368-6058-B72C5169E0DD -name IM_MOD_RL_wbmp_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::FD15A9C0-5C14-11CA-AA27-D66D638E58FC -name IM_MOD_RL_stegano_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::6668D58B-E040-328B-4AF4-14C738C172BA -name CORE_RL_jp2_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::871E464B-4566-1FC2-55CB-B65AEB416413 -name IM_MOD_RL_yuv_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::7D7A8325-4C69-B9D3-C832-803BCF999B5C -name coder.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B0A3651D-19B1-09F1-8197-1E58ED2CC704 -name IM_MOD_RL_null_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AB877243-6DAE-BF0C-70C2-F2D702B16231 -name IM_MOD_RL_pattern_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F571F366-1737-7E65-5441-DEBD166DE247 -name IM_MOD_RL_plasma_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::93F18CDE-B871-B2D4-3C0F-7C1B933E1ACB -name IM_MOD_RL_pcx_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D1567C76-29D0-C200-9FC7-F7E1399D3011 -name CORE_RL_xlib_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BEF1E1AC-9564-EA49-2B8F-1AAC9F6A7669 -name IM_MOD_RL_caption_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::2D14864E-6A39-FE03-4EA8-CCE7AC94487D -name comic2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::27CD65A5-D5F9-C982-5096-65298417EE61 -name IM_MOD_RL_url_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A273E901-0B63-390B-D44A-7240491C6F59 -name IM_MOD_RL_info_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B39B27EC-325A-D222-01FC-F6B3BC92E99A -name IM_MOD_RL_hdf_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BA634D39-716B-C895-73DD-2E5FA3CA2F9C -name CORE_RL_png_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::35560FB0-A7BD-54C7-C799-3EB2922BED2C -name delegates.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::FCE51670-E4AE-B813-6CFC-A7A9B627F72C -name IM_MOD_RL_matte_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::D10DB719-887D-4898-DAA8-8F1C6A4203B2 -name IM_MOD_RL_mono_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::78A66F97-ECEC-BFEC-75F2-2FA2087927C2 -name CORE_RL_jbig_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::FB74C41B-3F08-A9E8-B38D-C7C2FDFE9560 -name IM_MOD_RL_xtrn_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::ABC0A7AF-B14B-09BE-4756-76C8FE771517 -name IM_MOD_RL_vicar_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::F69B9AAD-EC2B-5EC7-5ED8-1395033DE0F5 -name IM_MOD_RL_psd_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::66CB1D9D-9995-F71C-155D-F1F4AA3B6D40 -name IM_MOD_RL_uyvy_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::4DB66BC3-4C48-C763-9BCA-9E831CA1FF0B -name IM_MOD_RL_art_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EB24F574-4226-6404-B069-7B46C04988E0 -name IM_MOD_RL_ycbcr_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A9990A18-D6A1-AA14-1EDF-FC43D8AE0C7E -name type-ghostscript.xml -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::5B72558A-192B-76EB-1BA8-C4CBA43C6C05 -name IM_MOD_RL_x_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::A3937F85-1D17-D3DD-2DF5-FB9FE4A99ADB -name IM_MOD_RL_dng_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B2C41CC1-EB2D-F7E7-B22E-0C154C4C96C1 -name IM_MOD_RL_html_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::68A62902-7F48-6E7A-E5D3-1F58C895B409 -name IM_MOD_RL_tim_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::E5C83E45-56B1-9BD7-7676-07CABD98E0BF -name IM_MOD_RL_tile_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::084206D9-98DB-DE2A-19BC-FD17A191096D -name IM_MOD_RL_xc_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::43BE7C18-6369-E035-8390-2E13C8CBB33C -name CORE_RL_zlib_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::EFC4D6E5-4FC9-25D5-B308-8CC8C13EF3A1 -name IM_MOD_RL_gif_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::05A8646B-F100-4803-5916-4CBAC154BFE9 -name IM_MOD_RL_sgi_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::1B354F22-4795-739A-A47D-8F2D99DFB58A -name IM_MOD_RL_ept_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B6725A29-1F09-2982-6BE1-29062A90F684 -name IM_MOD_RL_palm_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::445BD28F-0E70-B452-15B3-9E0C353CE345 -name IM_MOD_RL_ps_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::183A1789-2ED2-D555-AE4B-B7EBC97EB1D5 -name IM_MOD_RL_miff_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::69178142-77D3-D7C5-74C7-6F1597474123 -name IM_MOD_RL_vid_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::9D84C810-6DEC-5831-CFC6-AD0543D95881 -name IM_MOD_RL_rla_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::514DCC61-0BE9-6C5C-A970-170219D3A87E -name IM_MOD_RL_magick_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::AAF94AED-250D-DE8D-14C5-FA8BC05AAE74 -name IM_MOD_RL_djvu_.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::8E5D85A4-7608-47A1-CF7C-309060D5FF40 -filemethod {Always overwrite files} -type dir -directory <%InstallDir%> -name /home/kovid/work/calibre/build/py2exe -parent BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Main -parent Components SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Typical -parent SetupTypes @@ -508,9 +226,6 @@ InstallComponent 28FDA3F4-B799-901F-8A27-AA04F0C022AB -setup Install -type pane InstallComponent A75C97CC-01AC-C12A-D663-A54E3257F11B -setup Install -type action -title {Disable Buttons} -component ModifyWidget -active Yes -parent 28FDA3F4-B799-901F-8A27-AA04F0C022AB InstallComponent B6D03F99-8B73-BE6E-1050-721B286D3D60 -setup Install -type action -title {Execute Action} -component ExecuteAction -active Yes -parent 28FDA3F4-B799-901F-8A27-AA04F0C022AB InstallComponent 91AB3DE5-D61C-522D-5B3B-F2953E1DE771 -setup Install -type action -title {Move Forward} -component MoveForward -active Yes -parent 28FDA3F4-B799-901F-8A27-AA04F0C022AB -InstallComponent D6631BA5-577E-B30C-A73D-2B12B826811A -setup Install -type pane -conditions C6DE83DD-5C2A-AC5B-6ABA-84D73AE38655 -title {Install USB Driver} -component CustomBlankPane1 -command insert -active Yes -parent StandardInstall -Condition C6DE83DD-5C2A-AC5B-6ABA-84D73AE38655 -active Yes -parent D6631BA5-577E-B30C-A73D-2B12B826811A -title {Platform Condition} -component PlatformCondition -TreeObject::id C6DE83DD-5C2A-AC5B-6ABA-84D73AE38655 -InstallComponent 1B9E77A3-10D6-9EDD-160B-64B5EBB31981 -setup Install -type action -title {Add Widget} -component AddWidget -command reorder -active Yes -parent D6631BA5-577E-B30C-A73D-2B12B826811A InstallComponent 8A7FD0C2-F053-8764-F204-4BAE71E05708 -setup Install -type pane -title {Setup Complete} -component SetupComplete -active Yes -parent StandardInstall InstallComponent 710F2507-2557-652D-EA55-440D710EFDFA -setup Install -type action -conditions {69188956-D764-5B26-B048-46A4239C3733 08195201-0797-932C-4B51-E5EF9D1D41BD 2E18F4AE-F1BB-5C62-2900-73A576A49261} -title {Install USB Driver} -component ExecuteExternalProgram -command insert -alias {Install USB Driver} -active Yes -parent 8A7FD0C2-F053-8764-F204-4BAE71E05708 Condition 69188956-D764-5B26-B048-46A4239C3733 -active Yes -parent 710F2507-2557-652D-EA55-440D710EFDFA -title {Platform Condition} -component PlatformCondition -TreeObject::id 69188956-D764-5B26-B048-46A4239C3733 @@ -667,30 +382,6 @@ false 1ADA4DE6-31A7-E816-7719-4C8558F5378D,String <%UpgradeInstall%> -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Checked -No - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Conditions -{0 conditions} - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,ExecuteAction -{Before Pane is Displayed} - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Text,subst -1 - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Type -checkbutton - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,VirtualText -InstallUSBDriver - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,X -185 - -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Y -220 - 1CA13495-CB19-27A9-56E5-9BCF91958249,Comment {Ask the user if they want to proceed with the uninstall.} @@ -871,6 +562,9 @@ false 48596410-DF5A-1E56-D59C-1B1E2F094FCA,Conditions {1 condition} +48596410-DF5A-1E56-D59C-1B1E2F094FCA,IconPath +{<%InstallDir%>\library.ico} + 48596410-DF5A-1E56-D59C-1B1E2F094FCA,ShortcutName <%AppName%> @@ -1094,7 +788,7 @@ DevconStatus {} 77D1144B-1013-79B5-034B-5D6BDA6B2FD2,IconPath -{<%InstallDir%>\lrfviewer<%Ext%>} +{<%InstallDir%>\viewer.ico} 77D1144B-1013-79B5-034B-5D6BDA6B2FD2,InstallForAllUsers Yes @@ -1492,6 +1186,9 @@ system BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9,Destination <%InstallDir%> +BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9,FileUpdateMethod +{Always overwrite files} + BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9,Name {Program Files} @@ -1525,9 +1222,6 @@ C5416030-8AB4-3466-F341-9A0BBFEA55EF,String C5AD5B0C-26BE-16E5-899A-9A9436C8F688,ExitType Finish -C6DE83DD-5C2A-AC5B-6ABA-84D73AE38655,Platform -Windows - C7D6444E-DB8B-EE24-3E12-A2AF8A392C5D,Background white @@ -1567,33 +1261,15 @@ false CFBE4459-450B-1FAB-3422-609544334AA2,String <%InstallStopped%> -D6631BA5-577E-B30C-A73D-2B12B826811A,Active -Yes - -D6631BA5-577E-B30C-A73D-2B12B826811A,BackButton,subst -1 - -D6631BA5-577E-B30C-A73D-2B12B826811A,CancelButton,subst -1 - -D6631BA5-577E-B30C-A73D-2B12B826811A,Caption,subst -1 - -D6631BA5-577E-B30C-A73D-2B12B826811A,Conditions -{1 condition} - -D6631BA5-577E-B30C-A73D-2B12B826811A,Message,subst -1 - -D6631BA5-577E-B30C-A73D-2B12B826811A,NextButton,subst -1 - D79DC0D2-38BC-9D9F-2DF4-3C76D89BF933,ExitType Finish D86BBA5C-4903-33BA-59F8-4266A3D45896,Conditions {2 conditions} +D86BBA5C-4903-33BA-59F8-4266A3D45896,IconPath +{<%InstallDir%>\library.ico} + D86BBA5C-4903-33BA-59F8-4266A3D45896,ShortcutDirectory <%QUICK_LAUNCH%> @@ -1621,6 +1297,9 @@ Typical E32519F3-A540-C8F3-957F-4C1DB5B25DFE,Conditions {2 conditions} +E32519F3-A540-C8F3-957F-4C1DB5B25DFE,IconPath +{<%InstallDir%>\library.ico} + E32519F3-A540-C8F3-957F-4C1DB5B25DFE,ShortcutName <%AppName%> @@ -2205,9 +1884,6 @@ E611105F-DC85-9E20-4F7B-E63C54E5DF06,Message 1356216E-90D2-8324-0EEB-975A64F23EB8,Message <%InstallingApplicationText%> -1B9E77A3-10D6-9EDD-160B-64B5EBB31981,Text -{Install USB driver for the SONY PRS500} - 21B897C4-24BE-70D1-58EA-DE78EFA60719,Message {USB Driver installation failed with return code <%DevconStatus%> and console output \n\n<%DevconResult%>} @@ -2273,12 +1949,6 @@ C3E9E5D9-58C8-C2C5-DF75-21D908A64782,Message C7D6444E-DB8B-EE24-3E12-A2AF8A392C5D,Text <%CreateDesktopShortcutText%> -D6631BA5-577E-B30C-A73D-2B12B826811A,Caption -{Install USB Driver} - -D6631BA5-577E-B30C-A73D-2B12B826811A,Message -{If you intend to use <%AppName%> to manage your SONY PRS500, you have to install the USB driver. Note that you cannot use the PRS500 in both <%AppName%> and the SONY E-library software.} - D9ADE41C-B744-690C-2CED-CF826BF03D2E,Description <%TypicalInstallDescription%> diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 63de45ebc2..517a9975b7 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -6,8 +6,7 @@ __docformat__ = 'restructuredtext en' ''' Freeze app into executable using py2exe. ''' -QT_DIR = 'C:\\Qt\\4.4.0' -DEVCON = 'C:\\devcon\\i386\\devcon.exe' +QT_DIR = 'C:\\Qt\\4.4.1' LIBUSB_DIR = 'C:\\libusb' LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' PDFTOHTML = 'C:\\pdftohtml\\pdftohtml.exe' @@ -15,7 +14,7 @@ IMAGEMAGICK_DIR = 'C:\\ImageMagick' FONTCONFIG_DIR = 'C:\\fontconfig' -import sys, os, py2exe, shutil, zipfile, glob, subprocess +import sys, os, py2exe, shutil, zipfile, glob, subprocess, re from distutils.core import setup from distutils.filelist import FileList BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) @@ -23,6 +22,13 @@ sys.path.insert(0, BASE_DIR) from setup import VERSION, APPNAME, entry_points, scripts, basenames sys.path.remove(BASE_DIR) +ICONS = [os.path.abspath(os.path.join(BASE_DIR, 'icons', i)) for i in ('library.ico', 'viewer.ico')] +for icon in ICONS: + if not os.access(icon, os.R_OK): + raise Exception('No icon at '+icon) + +VERSION = re.sub('[a-z]\d+', '', VERSION) + PY2EXE_DIR = os.path.join(BASE_DIR, 'build','py2exe') class BuildEXE(py2exe.build_exe.py2exe): @@ -59,29 +65,18 @@ class BuildEXE(py2exe.build_exe.py2exe): shutil.copyfile(f, os.path.join(self.dist_dir, os.path.basename(f))) for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.pyd')): shutil.copyfile(f, os.path.join(tgt, os.path.basename(f))) - qtsvgdll = None - for other in self.other_depends: - if 'qtsvg4.dll' in other.lower(): - qtsvgdll = other - break shutil.copyfile('LICENSE', os.path.join(self.dist_dir, 'LICENSE')) print - if qtsvgdll: - print 'Adding', qtsvgdll - shutil.copyfile(qtsvgdll, os.path.join(self.dist_dir, os.path.basename(qtsvgdll))) - qtxmldll = os.path.join(os.path.dirname(qtsvgdll), 'QtXml4.dll') - print 'Adding', qtxmldll - shutil.copyfile(qtxmldll, - os.path.join(self.dist_dir, os.path.basename(qtxmldll))) + print 'Adding QtXml4.dll' + shutil.copyfile(os.path.join(QT_DIR, 'bin', 'QtXml4.dll'), + os.path.join(self.dist_dir, 'QtXml4.dll')) print 'Adding Qt plugins...', qt_prefix = QT_DIR - if qtsvgdll: - qt_prefix = os.path.dirname(os.path.dirname(qtsvgdll)) plugdir = os.path.join(qt_prefix, 'plugins') for d in ('imageformats', 'codecs', 'iconengines'): print d, imfd = os.path.join(plugdir, d) - tg = os.path.join(self.dist_dir, d) + tg = os.path.join(self.dist_dir, d) if os.path.exists(tg): shutil.rmtree(tg) shutil.copytree(imfd, tg) @@ -93,6 +88,11 @@ class BuildEXE(py2exe.build_exe.py2exe): f.write(i, i.partition('\\')[-1]) f.close() + print + print 'Copying icons' + for icon in ICONS: + shutil.copyfile(icon, os.path.join(PY2EXE_DIR, os.path.basename(icon))) + print print 'Adding third party dependencies' print '\tAdding devcon' @@ -101,7 +101,6 @@ class BuildEXE(py2exe.build_exe.py2exe): for pat in ('*.dll', '*.sys', '*.cat', '*.inf'): for f in glob.glob(os.path.join(LIBUSB_DIR, pat)): shutil.copyfile(f, os.path.join(tdir, os.path.basename(f))) - shutil.copyfile(DEVCON, os.path.join(tdir, os.path.basename(DEVCON))) print '\tAdding unrar' shutil.copyfile(LIBUNRAR, os.path.join(PY2EXE_DIR, os.path.basename(LIBUNRAR))) print '\tAdding pdftohtml' @@ -126,8 +125,8 @@ class BuildEXE(py2exe.build_exe.py2exe): @classmethod def manifest(cls, prog): cls.manifest_resource_id += 1 - return (24, cls.manifest_resource_id, - cls.MANIFEST_TEMPLATE % dict(prog=prog, version=VERSION+'.0')) + return (24, cls.manifest_resource_id, + cls.MANIFEST_TEMPLATE % dict(prog=prog, version=(VERSION+'.0'))) def main(args=sys.argv): @@ -137,18 +136,17 @@ def main(args=sys.argv): console = [dict(dest_base=basenames['console'][i], script=scripts['console'][i]) for i in range(len(scripts['console']))] - setup( cmdclass = {'py2exe': BuildEXE}, windows = [ {'script' : scripts['gui'][0], 'dest_base' : APPNAME, - 'icon_resources' : [(1, os.path.join(BASE_DIR, 'icons', 'library.ico'))], + 'icon_resources' : [(1, ICONS[0])], 'other_resources' : [BuildEXE.manifest(APPNAME)], }, {'script' : scripts['gui'][1], 'dest_base' : 'lrfviewer', - 'icon_resources' : [(1, os.path.join(BASE_DIR, 'icons', 'viewer.ico'))], + 'icon_resources' : [(1, ICONS[1])], 'other_resources' : [BuildEXE.manifest('lrfviewer')], }, ], @@ -163,12 +161,12 @@ def main(args=sys.argv): 'win32process', 'win32api', 'msvcrt', 'win32event', 'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*', - 'lxml', 'lxml._elementpath', 'genshi', + 'genshi', 'BeautifulSoup', 'path', 'pydoc', 'IPython.Extensions.*', 'calibre.web.feeds.recipes.*', 'PyQt4.QtWebKit', 'PyQt4.QtNetwork', ], - 'packages' : ['PIL'], + 'packages' : ['PIL', 'lxml'], 'excludes' : ["Tkconstants", "Tkinter", "tcl", "_imagingtk", "ImageTk", "FixTk" ], @@ -180,4 +178,4 @@ def main(args=sys.argv): return 0 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/pyqtdistutils.py b/pyqtdistutils.py index 2291efba01..252968fb60 100644 --- a/pyqtdistutils.py +++ b/pyqtdistutils.py @@ -10,7 +10,7 @@ from distutils.core import Extension from distutils.command.build_ext import build_ext as _build_ext from distutils.dep_util import newer_group from distutils import log - + import sipconfig, os, sys, string, glob, shutil from PyQt4 import pyqtconfig iswindows = 'win32' in sys.platform @@ -22,7 +22,7 @@ def replace_suffix(path, new_suffix): return os.path.splitext(path)[0] + new_suffix class PyQtExtension(Extension): - + def __init__(self, name, sources, sip_sources, **kw): ''' :param sources: Qt .cpp and .h files needed for this extension @@ -32,16 +32,16 @@ class PyQtExtension(Extension): self.module_makefile = pyqtconfig.QtGuiModuleMakefile self.sip_sources = map(lambda x: x.replace('/', os.sep), sip_sources) Extension.__init__(self, name, sources, **kw) - + class build_ext(_build_ext): - + def make(self, makefile): make = 'make' if iswindows: make = 'mingw32-make' self.spawn([make, '-f', makefile]) - + def build_qt_objects(self, ext, bdir): if not iswindows: bdir = os.path.join(bdir, 'qt') @@ -53,7 +53,7 @@ class build_ext(_build_ext): try: headers = set([f for f in sources if f.endswith('.h')]) sources = set(sources) - headers - name = ext.name.rpartition('.')[-1] + name = ext.name.rpartition('.')[-1] pro = '''\ TARGET = %s TEMPLATE = lib @@ -69,7 +69,7 @@ CONFIG += x86 ppc return map(os.path.abspath, glob.glob(pat)) finally: os.chdir(cwd) - + def build_sbf(self, sip, sbf, bdir): sip_bin = self.sipcfg.sip_bin self.spawn([sip_bin, @@ -78,10 +78,10 @@ CONFIG += x86 ppc '-I', self.pyqtcfg.pyqt_sip_dir, ] + self.pyqtcfg.pyqt_sip_flags.split()+ [sip]) - + def build_pyqt(self, bdir, sbf, ext, qtobjs, headers): makefile = ext.module_makefile(configuration=self.pyqtcfg, - build_file=sbf, dir=bdir, + build_file=sbf, dir=bdir, makefile='Makefile.pyqt', universal=OSX_SDK, qt=1) if 'win32' in sys.platform: @@ -95,14 +95,14 @@ CONFIG += x86 ppc self.make('Makefile.pyqt') finally: os.chdir(cwd) - - - + + + def build_extension(self, ext): self.inplace = True # Causes extensions to be built in the source tree if not isinstance(ext, PyQtExtension): return _build_ext.build_extension(self, ext) - + fullname = self.get_ext_fullname(ext.name) if self.inplace: # ignore build-lib -- put the compiled extension into @@ -122,20 +122,20 @@ CONFIG += x86 ppc bdir = os.path.abspath(os.path.join(self.build_temp, fullname)) if not os.path.exists(bdir): os.makedirs(bdir) - ext.sources = map(os.path.abspath, ext.sources) + ext.sources2 = map(os.path.abspath, ext.sources) qt_dir = 'qt\\release' if iswindows else 'qt' objects = set(map(lambda x: os.path.join(bdir, qt_dir, replace_suffix(os.path.basename(x), '.o')), - [s for s in ext.sources if not s.endswith('.h')])) + [s for s in ext.sources2 if not s.endswith('.h')])) newer = False for object in objects: - if newer_group(ext.sources, object, missing='newer'): + if newer_group(ext.sources2, object, missing='newer'): newer = True break - headers = [f for f in ext.sources if f.endswith('.h')] + headers = [f for f in ext.sources2 if f.endswith('.h')] if self.force or newer: log.info('building \'%s\' extension', ext.name) objects = self.build_qt_objects(ext, bdir) - + self.sipcfg = sipconfig.Configuration() self.pyqtcfg = pyqtconfig.Configuration() sbf_sources = [] @@ -148,19 +148,19 @@ CONFIG += x86 ppc generated_sources = [] for sbf in sbf_sources: generated_sources += self.get_sip_output_list(sbf, bdir) - + depends = generated_sources + list(objects) mod = os.path.join(bdir, os.path.basename(ext_filename)) - + if self.force or newer_group(depends, mod, 'newer'): self.build_pyqt(bdir, sbf_sources[0], ext, list(objects), headers) - + if self.force or newer_group([mod], ext_filename, 'newer'): if os.path.exists(ext_filename): os.unlink(ext_filename) shutil.copyfile(mod, ext_filename) shutil.copymode(mod, ext_filename) - + def get_sip_output_list(self, sbf, bdir): """ Parse the sbf file specified to extract the name of the generated source @@ -175,7 +175,7 @@ CONFIG += x86 ppc return out raise RuntimeError, "cannot parse SIP-generated '%s'" % sbf - + def run_sip(self, sip_files): sip_bin = self.sipcfg.sip_bin sip_sources = [i[0] for i in sip_files] @@ -191,6 +191,5 @@ CONFIG += x86 ppc ] + self.pyqtcfg.pyqt_sip_flags.split()+ [sip]) generated_sources += self.get_sip_output_list(sbf) - return generated_sources - - \ No newline at end of file + return generated_sources + diff --git a/resources.py b/resources.py deleted file mode 100644 index e5b426e2a4..0000000000 --- a/resources.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python - -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' -''' -Compile resource files. -''' -import os, sys, glob -sys.path.insert(1, os.path.join(os.getcwd(), 'src')) -from calibre import __appname__ - -RESOURCES = dict( - opf_template = '%p/ebooks/metadata/opf.xml', - ncx_template = '%p/ebooks/metadata/ncx.xml', - fb2_xsl = '%p/ebooks/lrf/fb2/fb2.xsl', - metadata_sqlite = '%p/library/metadata_sqlite.sql', - ) - -def main(args=sys.argv): - data = '' - for key, value in RESOURCES.items(): - path = value.replace('%p', 'src'+os.sep+__appname__) - bytes = repr(open(path, 'rb').read()) - data += key + ' = ' + bytes + '\n\n' - - translations_found = False - for TPATH in ('/usr/share/qt4/translations', '/usr/lib/qt4/translations'): - if os.path.exists(TPATH): - files = glob.glob(TPATH + '/qt_??.qm') - - for f in files: - key = os.path.basename(f).partition('.')[0] - bytes = repr(open(f, 'rb').read()) - data += key + ' = ' + bytes + '\n\n' - translations_found = True - break - if not translations_found: - print 'WARNING: Could not find Qt transations' - - dest = os.path.abspath(os.path.join('src', __appname__, 'resources.py')) - print 'Writing resources to', dest - open(dest, 'wb').write(data) - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/setup.py b/setup.py index 0292aba9c0..3140e66f27 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import sys, re, os, shutil +import sys, re, os, shutil, cStringIO, tempfile, subprocess sys.path.append('src') iswindows = re.search('win(32|64)', sys.platform) isosx = 'darwin' in sys.platform @@ -48,66 +48,294 @@ main_functions = { if __name__ == '__main__': from setuptools import setup, find_packages, Extension from distutils.command.build import build as _build - from distutils.core import Command + from distutils.core import Command as _Command from pyqtdistutils import PyQtExtension, build_ext import subprocess, glob - class pot(Command): - user_options = [] - def initialize_options(self): pass - def finalize_options(self): pass - - def run(self): - from calibre.translations import create_pot - create_pot() - - def build_manual(): - cwd = os.path.abspath(os.getcwd()) - os.chdir(os.path.join('src', 'calibre', 'manual')) - try: - for d in ('.build', 'cli'): - if os.path.exists(d): - shutil.rmtree(d) - os.makedirs(d) - if not os.path.exists('.build'+os.sep+'html'): - os.makedirs('.build'+os.sep+'html') - subprocess.check_call(['sphinx-build', '-b', 'custom', '-d', - '.build/doctrees', '.', '.build/html']) - finally: - os.chdir(cwd) + def newer(targets, sources): + ''' + Return True is sources is newer that targets or if targets + does not exist. + ''' + for f in targets: + if not os.path.exists(f): + return True + ttimes = map(lambda x: os.stat(x).st_mtime, targets) + stimes = map(lambda x: os.stat(x).st_mtime, sources) + newest_source, oldest_target = max(stimes), min(ttimes) + return newest_source > oldest_target - class manual(Command): + class Command(_Command): user_options = [] def initialize_options(self): pass def finalize_options(self): pass + + class sdist(Command): + + description = "create a source distribution using bzr" def run(self): - build_manual() + name = 'dist/calibre-%s.tar.gz'%VERSION + subprocess.check_call(('bzr export '+name).split()) + self.distribution.dist_files.append(('sdist', '', name)) + + class pot(Command): + description = '''Create the .pot template for all translatable strings''' + + PATH = os.path.join('src', APPNAME, 'translations') + + def source_files(self): + ans = [] + for root, dirs, files in os.walk(os.path.dirname(self.PATH)): + for name in files: + if name.endswith('.py'): + ans.append(os.path.abspath(os.path.join(root, name))) + return ans + + + def run(self): + sys.path.insert(0, os.path.abspath(self.PATH)) + try: + from pygettext import main as pygettext + files = self.source_files() + buf = cStringIO.StringIO() + print 'Creating translations template' + tempdir = tempfile.mkdtemp() + pygettext(buf, ['-p', tempdir]+files) + src = buf.getvalue() + pot = os.path.join(tempdir, 'calibre.pot') + f = open(pot, 'wb') + f.write(src) + f.close() + print 'Translations template:', pot + return pot + finally: + sys.path.remove(os.path.abspath(self.PATH)) + class manual(Command): + description='''Build the User Manual ''' + + def run(self): + cwd = os.path.abspath(os.getcwd()) + os.chdir(os.path.join('src', 'calibre', 'manual')) + try: + for d in ('.build', 'cli'): + if os.path.exists(d): + shutil.rmtree(d) + os.makedirs(d) + if not os.path.exists('.build'+os.sep+'html'): + os.makedirs('.build'+os.sep+'html') + subprocess.check_call(['sphinx-build', '-b', 'custom', '-d', + '.build/doctrees', '.', '.build/html']) + finally: + os.chdir(cwd) + + @classmethod + def clean(cls): + path = os.path.join('src', 'calibre', 'manual', '.build') + if os.path.exists(path): + shutil.rmtree(path) + + class resources(Command): + description='''Compile various resource files used in calibre. ''' + + RESOURCES = dict( + opf_template = 'ebooks/metadata/opf.xml', + ncx_template = 'ebooks/metadata/ncx.xml', + fb2_xsl = 'ebooks/lrf/fb2/fb2.xsl', + metadata_sqlite = 'library/metadata_sqlite.sql', + ) + + DEST = os.path.join('src', APPNAME, 'resources.py') + + def get_qt_translations(self): + data = {} + translations_found = False + for TPATH in ('/usr/share/qt4/translations', '/usr/lib/qt4/translations'): + if os.path.exists(TPATH): + files = glob.glob(TPATH + '/qt_??.qm') + for f in files: + key = os.path.basename(f).partition('.')[0] + data[key] = f + translations_found = True + break + if not translations_found: + print 'WARNING: Could not find Qt transations' + return data + + def run(self): + data, dest, RESOURCES = {}, self.DEST, self.RESOURCES + for key in RESOURCES: + path = RESOURCES[key] + if not os.path.isabs(path): + RESOURCES[key] = os.path.join('src', APPNAME, path) + translations = self.get_qt_translations() + RESOURCES.update(translations) + if newer([dest], RESOURCES.values()): + print 'Compiling resources...' + with open(dest, 'wb') as f: + for key in RESOURCES: + data = open(RESOURCES[key], 'rb').read() + f.write(key + ' = ' + repr(data)+'\n\n') + else: + print 'Resources are up to date' + + @classmethod + def clean(cls): + path = cls.DEST + for path in glob.glob(path+'*'): + if os.path.exists(path): + os.remove(path) + + class translations(Command): + description='''Compile the translations''' + PATH = os.path.join('src', APPNAME, 'translations') + DEST = os.path.join(PATH, 'compiled.py') + + def run(self): + sys.path.insert(0, os.path.abspath(self.PATH)) + try: + files = glob.glob(os.path.join(self.PATH, '*.po')) + if newer([self.DEST], files): + from msgfmt import main as msgfmt + translations = {} + print 'Compiling translations...' + for po in files: + lang = os.path.basename(po).partition('.')[0] + buf = cStringIO.StringIO() + print 'Compiling', lang + msgfmt(buf, [po]) + translations[lang] = buf.getvalue() + open(self.DEST, 'wb').write('translations = '+repr(translations)) + else: + print 'Translations up to date' + finally: + sys.path.remove(os.path.abspath(self.PATH)) + + + @classmethod + def clean(cls): + path = cls.DEST + if os.path.exists(path): + os.remove(path) + + + class gui(Command): + description='''Compile all GUI forms and images''' + PATH = os.path.join('src', APPNAME, 'gui2') + IMAGES_DEST = os.path.join(PATH, 'images_rc.py') + + @classmethod + def find_forms(cls): + forms = [] + for root, dirs, files in os.walk(cls.PATH): + for name in files: + if name.endswith('.ui'): + forms.append(os.path.abspath(os.path.join(root, name))) + + return forms + + @classmethod + def form_to_compiled_form(cls, form): + return form.rpartition('.')[0]+'_ui.py' + + def run(self): + self.build_forms() + self.build_images() + + def build_images(self): + cwd, images = os.getcwd(), os.path.basename(self.IMAGES_DEST) + try: + os.chdir(self.PATH) + sources, files = [], [] + for root, dirs, files in os.walk('images'): + for name in files: + sources.append(os.path.join(root, name)) + if newer([images], sources): + print 'Compiling images...' + for s in sources: + alias = ' alias="library"' if s.endswith('images'+os.sep+'library.png') else '' + files.append('%s'%(alias, s)) + manifest = '\n\n%s\n\n'%'\n'.join(files) + with open('images.qrc', 'wb') as f: + f.write(manifest) + subprocess.check_call(['pyrcc4', '-o', images, 'images.qrc']) + else: + print 'Images are up to date' + finally: + os.chdir(cwd) + + + def build_forms(self): + from PyQt4.uic import compileUi + forms = self.find_forms() + for form in forms: + compiled_form = self.form_to_compiled_form(form) + if not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime: + print 'Compiling form', form + buf = cStringIO.StringIO() + compileUi(form, buf) + dat = buf.getvalue() + dat = dat.replace('__appname__', APPNAME) + dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc') + dat = dat.replace('from library import', 'from calibre.gui2.library import') + dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import') + dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?' __docformat__ = 'restructuredtext en' - -import sys, os, re, logging, time, subprocess, mechanize, atexit +import sys, os, re, logging, time, subprocess, atexit from htmlentitydefs import name2codepoint from math import floor from logging import Formatter @@ -15,7 +14,7 @@ from calibre.constants import iswindows, isosx, islinux, isfrozen, \ terminal_controller, preferred_encoding, \ __appname__, __version__, __author__, \ win32event, win32api, winerror, fcntl - +import mechanize def unicode_path(path, abs=False): if not isinstance(path, unicode): @@ -95,7 +94,7 @@ def filename_to_utf8(name): def extract(path, dir): ext = os.path.splitext(path)[1][1:].lower() extractor = None - if ext in ['zip', 'cbz', 'epub']: + if ext in ['zip', 'cbz', 'epub', 'oebzip']: from calibre.libunzip import extract as zipextract extractor = zipextract elif ext in ['cbr', 'rar']: @@ -139,9 +138,16 @@ def get_proxies(): return proxies -def browser(honor_time=False): +def browser(honor_time=True, max_time=2): + ''' + Create a mechanize browser for web scraping. The browser handles cookies, + refresh requests and ignores robots.txt. Also uses proxy if avaialable. + + :param honor_time: If True honors pause time in refresh requests + :param max_time: Maximum time in seconds to wait during a refresh request + ''' opener = mechanize.Browser() - opener.set_handle_refresh(True, honor_time=honor_time) + opener.set_handle_refresh(True, max_time=max_time, honor_time=honor_time) opener.set_handle_robots(False) opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; i686 Linux; en_US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4')] http_proxy = get_proxies().get('http', None) @@ -156,7 +162,7 @@ def fit_image(width, height, pwidth, pheight): @param height: Height of image @param pwidth: Width of box @param pheight: Height of box - @return: scaled, new_width, new_height. scaled is True iff new_widdth and/or new_height is different from width or height. + @return: scaled, new_width, new_height. scaled is True iff new_width and/or new_height is different from width or height. ''' scaled = height > pheight or width > pwidth if height > pheight: @@ -171,6 +177,19 @@ def fit_image(width, height, pwidth, pheight): return scaled, int(width), int(height) +class CurrentDir(object): + + def __init__(self, path): + self.path = path + self.cwd = None + + def __enter__(self, *args): + self.cwd = os.getcwd() + os.chdir(self.path) + return self.cwd + + def __exit__(self, *args): + os.chdir(self.cwd) def sanitize_file_name(name): ''' @@ -265,14 +284,36 @@ def english_sort(x, y): class LoggingInterface: def __init__(self, logger): - self.__logger = logger + self.__logger = self.logger = logger + + def setup_cli_handler(self, verbosity): + for handler in self.__logger.handlers: + if isinstance(handler, logging.StreamHandler): + return + if os.environ.get('CALIBRE_WORKER', None) is not None and self.__logger.handlers: + return + stream = sys.stdout + formatter = logging.Formatter() + level = logging.INFO + if verbosity > 0: + formatter = ColoredFormatter('[%(levelname)s] %(message)s') if verbosity > 1 else \ + ColoredFormatter('%(levelname)s: %(message)s') + level = logging.DEBUG + if verbosity > 1: + stream = sys.stderr + + handler = logging.StreamHandler(stream) + handler.setFormatter(formatter) + handler.setLevel(level) + self.__logger.addHandler(handler) + self.__logger.setLevel(level) + def ___log(self, func, msg, args, kwargs): args = [msg] + list(args) for i in range(len(args)): if isinstance(args[i], unicode): args[i] = args[i].encode(preferred_encoding, 'replace') - func(*args, **kwargs) def log_debug(self, msg, *args, **kwargs): @@ -296,13 +337,19 @@ class LoggingInterface: def log_exception(self, msg, *args): self.___log(self.__logger.exception, msg, args, {}) +def walk(dir): + ''' A nice interface to os.walk ''' + for record in os.walk(dir): + for f in record[-1]: + yield os.path.join(record[0], f) def strftime(fmt, t=time.localtime()): - ''' - A version of strtime that returns unicode strings. - ''' - result = time.strftime(fmt, t) - return unicode(result, preferred_encoding, 'replace') + ''' A version of strtime that returns unicode strings. ''' + if iswindows: + if isinstance(fmt, unicode): + fmt = fmt.encode('mbcs') + return plugins['winutil'][0].strftime(fmt, t) + return time.strftime(fmt, t).decode(preferred_encoding, 'replace') def entity_to_unicode(match, exceptions=[], encoding='cp1252'): ''' diff --git a/src/calibre/constants.py b/src/calibre/constants.py index f9a2380b41..a8414a71d8 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,13 +2,13 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.4.83' +__version__ = '0.4.92' __author__ = "Kovid Goyal " ''' Various run time constants. ''' -import sys, locale, codecs +import sys, locale, codecs, os from calibre.utils.terminfo import TerminalController terminal_controller = TerminalController(sys.stdout) @@ -16,7 +16,7 @@ terminal_controller = TerminalController(sys.stdout) iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower() isosx = 'darwin' in sys.platform.lower() islinux = not(iswindows or isosx) -isfrozen = hasattr(sys, 'frozen') +isfrozen = hasattr(sys, 'frozen') try: preferred_encoding = locale.getpreferredencoding() @@ -27,4 +27,37 @@ except: win32event = __import__('win32event') if iswindows else None winerror = __import__('winerror') if iswindows else None win32api = __import__('win32api') if iswindows else None -fcntl = None if iswindows else __import__('fcntl') \ No newline at end of file +fcntl = None if iswindows else __import__('fcntl') + +################################################################################ +plugins = None +if plugins is None: + # Load plugins + def load_plugins(): + plugins = {} + if isfrozen: + if iswindows: + plugin_path = os.path.join(os.path.dirname(sys.executable), 'plugins') + sys.path.insert(1, os.path.dirname(sys.executable)) + elif isosx: + plugin_path = os.path.join(getattr(sys, 'frameworks_dir'), 'plugins') + elif islinux: + plugin_path = os.path.join(getattr(sys, 'frozen_path'), 'plugins') + sys.path.insert(0, plugin_path) + else: + import pkg_resources + plugin_path = getattr(pkg_resources, 'resource_filename')('calibre', 'plugins') + sys.path.insert(0, plugin_path) + + for plugin in ['pictureflow', 'lzx', 'msdes'] + \ + (['winutil'] if iswindows else []) + \ + (['usbobserver'] if isosx else []): + try: + p, err = __import__(plugin), '' + except Exception, err: + p = None + err = str(err) + plugins[plugin] = (p, err) + return plugins + + plugins = load_plugins() diff --git a/src/calibre/debug.py b/src/calibre/debug.py index 12bc4f8063..796e98c8d5 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -21,13 +21,13 @@ Run an embedded python interpreter. 'Module specifications are of the form full.name.of.module,path_to_module.py', default=None ) parser.add_option('-c', '--command', help='Run python code.', default=None) + parser.add_option('--migrate', action='store_true', default=False, + help='Migrate old database. Needs two arguments. Path to library1.db and path to new library folder.', default=False) return parser def update_zipfile(zipfile, mod, path): if 'win32' in sys.platform: - print 'WARNING: On Windows Vista you must run this from a console that has been started in Administrator mode.' - print 'Press Enter to continue if this is an Administrator console or Ctrl-C to Cancel' - raw_input() + print 'WARNING: On Windows Vista using this option may cause windows to put library.zip into the Virtual Store (typically located in c:\Users\username\AppData\Local\VirtualStore). If it does this you must delete it from there after you\'re done debugging).' pat = re.compile(mod.replace('.', '/')+r'\.py[co]*') name = mod.replace('.', '/') + os.path.splitext(path)[-1] update(zipfile, [pat], [path], [name]) @@ -47,6 +47,29 @@ def update_module(mod, path): else: raise ValueError('Updating modules is not supported on this platform.') +def migrate(old, new): + from calibre.utils.config import prefs + from calibre.library.database import LibraryDatabase + from calibre.library.database2 import LibraryDatabase2 + from calibre.utils.terminfo import ProgressBar + from calibre import terminal_controller + class Dummy(ProgressBar): + def setLabelText(self, x): pass + def setAutoReset(self, y): pass + def reset(self): pass + def setRange(self, min, max): + self.min = min + self.max = max + def setValue(self, val): + self.update(float(val)/getattr(self, 'max', 1)) + + db = LibraryDatabase(old) + db2 = LibraryDatabase2(new) + db2.migrate_old(db, Dummy(terminal_controller, 'Migrating database...')) + prefs['library_path'] = os.path.abspath(new) + print 'Database migrated to', os.path.abspath(new) + + def main(args=sys.argv): opts, args = option_parser().parse_args(args) if opts.update_module: @@ -55,6 +78,11 @@ def main(args=sys.argv): elif opts.command: sys.argv = args[:1] exec opts.command + elif opts.migrate: + if len(args) < 3: + print 'You must specify the path to library1.db and the path to the new library folder' + return 1 + migrate(args[1], args[2]) else: from IPython.Shell import IPShellEmbed ipshell = IPShellEmbed() diff --git a/src/calibre/devices/prs500/books.py b/src/calibre/devices/prs500/books.py index db25e7d14c..6c57920487 100644 --- a/src/calibre/devices/prs500/books.py +++ b/src/calibre/devices/prs500/books.py @@ -258,7 +258,7 @@ class BookList(_BookList): if book is not None: self.remove_book(name) node = self.document.createElement(self.prefix + "text") - mime = MIME_MAP[name[name.rfind(".")+1:]] + mime = MIME_MAP[name[name.rfind(".")+1:].lower()] cid = self.max_id()+1 sourceid = str(self[0].sourceid) if len(self) else "1" attrs = { diff --git a/src/calibre/devices/prs505/books.py b/src/calibre/devices/prs505/books.py index a917aa00ae..f42f1b5513 100644 --- a/src/calibre/devices/prs505/books.py +++ b/src/calibre/devices/prs505/books.py @@ -13,7 +13,7 @@ from calibre.devices.interface import BookList as _BookList from calibre.devices import strftime as _strftime from calibre.devices import strptime -strftime = functools.partial(_strftime, zone=time.localtime) +strftime = functools.partial(_strftime, zone=time.gmtime) MIME_MAP = { "lrf" : "application/x-sony-bbeb", @@ -184,7 +184,7 @@ class BookList(_BookList): self.remove_book(name) node = self.document.createElement(self.prefix + "text") - mime = MIME_MAP[name.rpartition('.')[-1]] + mime = MIME_MAP[name.rpartition('.')[-1].lower()] cid = self.max_id()+1 sourceid = str(self[0].sourceid) if len(self) else "1" attrs = { @@ -277,9 +277,12 @@ class BookList(_BookList): def purge_empty_playlists(self): ''' Remove all playlists that have no children. Also removes any invalid playlist items.''' for pli in self.playlist_items(): - if not self.is_id_valid(pli.getAttribute('id')): - pli.parentNode.removeChild(pli) - pli.unlink() + try: + if not self.is_id_valid(pli.getAttribute('id')): + pli.parentNode.removeChild(pli) + pli.unlink() + except: + continue for pl in self.playlists(): empty = True for c in pl.childNodes: diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 5fc2b0c1cd..cc280c3eed 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -31,7 +31,7 @@ class PRS505(Device): PRODUCT_ID = 0x031e #: Product Id for the PRS-505 PRODUCT_NAME = 'PRS-505' VENDOR_NAME = 'SONY' - FORMATS = ["lrf", 'epub', "rtf", "pdf", "txt"] + FORMATS = ['lrf', 'epub', "rtf", "pdf", "txt"] MEDIA_XML = 'database/cache/media.xml' CACHE_XML = 'Sony Reader/database/cache.xml' @@ -39,9 +39,7 @@ class PRS505(Device): MAIN_MEMORY_VOLUME_LABEL = 'Sony Reader Main Memory' STORAGE_CARD_VOLUME_LABEL = 'Sony Reader Storage Card' - OSX_MAIN_NAME = 'Sony PRS-505/UC Media' - OSX_SD_NAME = 'Sony PRS-505/UC:SD Media' - OSX_MS_NAME = 'Sony PRS-505/UC:MS Media' + OSX_NAME = 'Sony PRS-505' CARD_PATH_PREFIX = __appname__ @@ -101,29 +99,42 @@ class PRS505(Device): return True return False + @classmethod + def get_osx_mountpoints(cls, raw=None): + if raw is None: + raw = subprocess.Popen('ioreg -w 0 -S -c IOMedia'.split(), + stdout=subprocess.PIPE).stdout.read() + lines = raw.splitlines() + names = {} + for i, line in enumerate(lines): + if line.strip().endswith('') and cls.OSX_NAME in line: + loc = 'stick' if ':MS' in line else 'card' if ':SD' in line else 'main' + for line in lines[i+1:]: + line = line.strip() + if line.endswith('}'): + break + match = re.search(r'"BSD Name"\s+=\s+"(.*?)"', line) + if match is not None: + names[loc] = match.group(1) + break + if len(names.keys()) == 3: + break + return names + + def open_osx(self): mount = subprocess.Popen('mount', shell=True, stdout=subprocess.PIPE).stdout.read() - src = subprocess.Popen('ioreg -n "%s"'%(self.OSX_MAIN_NAME,), - shell=True, stdout=subprocess.PIPE).stdout.read() - try: - devname = re.search(r'BSD Name.*=\s+"(\S+)"', src).group(1) - self._main_prefix = re.search('/dev/%s(\w*)\s+on\s+([^\(]+)\s+'%(devname,), mount).group(2) + os.sep - except: + names = self.get_osx_mountpoints() + dev_pat = r'/dev/%s(\w*)\s+on\s+([^\(]+)\s+' + if 'main' not in names.keys(): raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.')%self.__class__.__name__) - try: - src = subprocess.Popen('ioreg -n "%s"'%(self.OSX_SD_NAME,), - shell=True, stdout=subprocess.PIPE).stdout.read() - devname = re.search(r'BSD Name.*=\s+"(\S+)"', src).group(1) - except: - try: - src = subprocess.Popen('ioreg -n "%s"'%(self.OSX_MS_NAME,), - shell=True, stdout=subprocess.PIPE).stdout.read() - devname = re.search(r'BSD Name.*=\s+"(\S+)"', src).group(1) - except: - devname = None - if devname is not None: - self._card_prefix = re.search('/dev/%s(\w*)\s+on\s+([^\(]+)\s+'%(devname,), mount).group(2) + os.sep + main_pat = dev_pat%names['main'] + self._main_prefix = re.search(main_pat, mount).group(2) + os.sep + card_pat = names['stick'] if 'stick' in names.keys() else names['card'] if 'card' in names.keys() else None + if card_pat is not None: + card_pat = dev_pat%card_pat + self._card_prefix = re.search(card_pat, mount).group(2) + os.sep def open_windows_nowmi(self): @@ -280,8 +291,15 @@ class PRS505(Device): if prefix is None: return 0, 0 win32file = __import__('win32file', globals(), locals(), [], -1) - sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters = \ + try: + sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters = \ win32file.GetDiskFreeSpace(prefix[:-1]) + except Exception, err: + if getattr(err, 'args', [None])[0] == 21: # Disk not ready + time.sleep(3) + sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters = \ + win32file.GetDiskFreeSpace(prefix[:-1]) + else: raise mult = sectors_per_cluster * bytes_per_sector return total_clusters * mult, free_clusters * mult @@ -452,10 +470,14 @@ class PRS505(Device): def sync_booklists(self, booklists, end_session=True): fix_ids(*booklists) + if not os.path.exists(self._main_prefix): + os.makedirs(self._main_prefix) f = open(self._main_prefix + self.__class__.MEDIA_XML, 'wb') booklists[0].write(f) f.close() if self._card_prefix is not None and hasattr(booklists[1], 'write'): + if not os.path.exists(self._card_prefix): + os.makedirs(self._card_prefix) f = open(self._card_prefix + self.__class__.CACHE_XML, 'wb') booklists[1].write(f) f.close() diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index 2716963e8d..83153fd8b8 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -15,6 +15,10 @@ class ConversionError(Exception): class UnknownFormatError(Exception): pass -BOOK_EXTENSIONS = ['lrf', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm', - 'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw', - 'epub', 'fb2', 'djvu', 'lrx', 'cbr', 'cbz'] +class DRMError(ValueError): + pass + +BOOK_EXTENSIONS = ['lrf', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm', + 'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw', + 'epub', 'fb2', 'djvu', 'lrx', 'cbr', 'cbz', 'oebzip', + 'rb', 'imp', 'odt'] diff --git a/src/calibre/ebooks/chardet/__init__.py b/src/calibre/ebooks/chardet/__init__.py index 55257e1962..03d8fc2ea0 100644 --- a/src/calibre/ebooks/chardet/__init__.py +++ b/src/calibre/ebooks/chardet/__init__.py @@ -29,7 +29,13 @@ def detect(aBuf): return u.result # Added by Kovid -def xml_to_unicode(raw, verbose=False): +ENCODING_PATS = [ + re.compile(r'<[^<>]+encoding=[\'"](.*?)[\'"][^<>]*>', re.IGNORECASE), + re.compile(r'', re.IGNORECASE) + ] +ENTITY_PATTERN = re.compile(r'&(\S+?);') + +def xml_to_unicode(raw, verbose=False, strip_encoding_pats=False, resolve_entities=False): ''' Force conversion of byte string to unicode. Tries to look for XML/HTML encoding declaration first, if not found uses the chardet library and @@ -41,11 +47,14 @@ def xml_to_unicode(raw, verbose=False): return u'', encoding if isinstance(raw, unicode): return raw, encoding - match = re.compile(r'<[^<>]+encoding=[\'"](.*?)[\'"][^<>]*>', re.IGNORECASE).search(raw) - if match is None: - match = re.compile(r' + + + + + + '''%opf_name + zf = ZipFile(path_to_container, 'w') + zf.writestr('mimetype', 'application/epub+zip', compression=ZIP_STORED) + zf.writestr('META-INF/', '', 0700) + zf.writestr('META-INF/container.xml', CONTAINER) + return zf + +def config(defaults=None): + desc = _('Options to control the conversion to EPUB') + if defaults is None: + c = Config('epub', desc) + else: + c = StringConfig(defaults, desc) + + c.update(common_config()) + c.remove_opt('output') + 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.')) + 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()))) + 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=_('''\ +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 +well as any tags that have class="chapter". +The expression used must evaluate to a list of elements. To disable chapter detection, +use the expression "/". See the XPath Tutorial in the calibre User Manual for further +help on using this feature. +''').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.')) + 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.')) + + toc = c.add_group('toc', + _('''\ +Control the automatic generation of a Table of Contents. If an OPF file is detected +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.')) + 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.')) + 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.')) + 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.')) + 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.')) + 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.')) + + layout = c.add_group('page layout', _('Control page layout')) + layout('margin_top', ['--margin-top'], default=5.0, + help=_('Set the top margin in pts. Default is %default')) + layout('margin_bottom', ['--margin-bottom'], default=5.0, + help=_('Set the bottom margin in pts. Default is %default')) + layout('margin_left', ['--margin-left'], default=5.0, + help=_('Set the left margin in pts. Default is %default')) + 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.')) + layout('remove_paragraph_spacing', ['--remove-paragraph-spacing'], default=True, + help=_('Remove spacing between paragraphs. Will not work if the source file forces inter-paragraph spacing.')) + + 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, + 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 diff --git a/src/calibre/ebooks/epub/fonts.py b/src/calibre/ebooks/epub/fonts.py new file mode 100644 index 0000000000..5d0887f2d0 --- /dev/null +++ b/src/calibre/ebooks/epub/fonts.py @@ -0,0 +1,300 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Font size rationalization. See :function:`relativize`. +''' + +import logging, re, operator, functools, collections, unittest, copy, sys +from xml.dom import SyntaxErr + +from lxml.cssselect import CSSSelector +from lxml import etree +from lxml.html import HtmlElement + +from calibre.ebooks.html import fromstring +from calibre.ebooks.epub import rules +from cssutils import CSSParser + +num = r'[-]?\d+|[-]?\d*\.\d+' +length = r'(?P0)|(?P{num})(?P%|em|ex|px|in|cm|mm|pt|pc)'.replace('{num}', num) +absolute_size = r'(?P(x?x-)?(small|large)|medium)' +relative_size = r'(?Psmaller|larger)' + +font_size_pat = re.compile('|'.join((relative_size, absolute_size, length)), re.I) +line_height_pat = re.compile(r'({num})(px|in|cm|mm|pt|pc)'.replace('{num}', num)) + +PTU = { + 'in' : 72., + 'cm' : 72/2.54, + 'mm' : 72/25.4, + 'pt' : 1.0, + 'pc' : 1/12., + } + +DEFAULT_FONT_SIZE = 12 + +class Rationalizer(object): + + @classmethod + def specificity(cls, s): + '''Map CSS specificity tuple to a single integer''' + return sum([10**(4-i) + x for i,x in enumerate(s)]) + + @classmethod + def compute_font_size(cls, elem): + ''' + Calculate the effective font size of an element traversing its ancestors as far as + neccessary. + ''' + cfs = elem.computed_font_size + if cfs is not None: + return + sfs = elem.specified_font_size + if callable(sfs): + parent = elem.getparent() + cls.compute_font_size(parent) + elem.computed_font_size = sfs(parent.computed_font_size) + else: + elem.computed_font_size = sfs + + @classmethod + def calculate_font_size(cls, style): + 'Return font size in pts from style object. For relative units returns a callable' + match = font_size_pat.search(style.font) + fs = '' + if match: + fs = match.group() + if style.fontSize: + fs = style.fontSize + + match = font_size_pat.search(fs) + if match is None: + return None + match = match.groupdict() + unit = match.get('unit', '') + if unit: unit = unit.lower() + if unit in PTU.keys(): + return PTU[unit] * float(match['num']) + if unit in ('em', 'ex'): + return functools.partial(operator.mul, float(match['num'])) + if unit == '%': + return functools.partial(operator.mul, float(match['num'])/100.) + abs = match.get('abs', '') + if abs: abs = abs.lower() + if abs: + x = (1.2)**(abs.count('x') * (-1 if 'small' in abs else 1)) + return 12 * x + if match.get('zero', False): + return 0. + return functools.partial(operator.mul, 1.2) if 'larger' in fs.lower() else functools.partial(operator.mul, 0.8) + + @classmethod + def resolve_rules(cls, stylesheets): + for sheet in stylesheets: + if hasattr(sheet, 'fs_rules'): + continue + sheet.fs_rules = [] + sheet.lh_rules = [] + for r in sheet: + if r.type == r.STYLE_RULE: + font_size = cls.calculate_font_size(r.style) + if font_size is not None: + for s in r.selectorList: + sheet.fs_rules.append([CSSSelector(s.selectorText), font_size]) + orig = line_height_pat.search(r.style.lineHeight) + if orig is not None: + for s in r.selectorList: + sheet.lh_rules.append([CSSSelector(s.selectorText), float(orig.group(1)) * PTU[orig.group(2).lower()]]) + + + @classmethod + def apply_font_size_rules(cls, stylesheets, root): + 'Add a ``specified_font_size`` attribute to every element that has a specified font size' + cls.resolve_rules(stylesheets) + for sheet in stylesheets: + for selector, font_size in sheet.fs_rules: + elems = selector(root) + for elem in elems: + elem.specified_font_size = font_size + + @classmethod + def remove_font_size_information(cls, stylesheets): + for r in rules(stylesheets): + r.style.removeProperty('font-size') + try: + new = font_size_pat.sub('', r.style.font).strip() + if new: + r.style.font = new + else: + r.style.removeProperty('font') + except SyntaxErr: + r.style.removeProperty('font') + if line_height_pat.search(r.style.lineHeight) is not None: + r.style.removeProperty('line-height') + + @classmethod + def compute_font_sizes(cls, root, stylesheets, base=12): + stylesheets = [s for s in stylesheets if hasattr(s, 'cssText')] + cls.apply_font_size_rules(stylesheets, root) + + # Compute the effective font size of all tags + root.computed_font_size = DEFAULT_FONT_SIZE + for elem in root.iter(etree.Element): + cls.compute_font_size(elem) + + extra_css = {} + if base > 0: + # Calculate the "base" (i.e. most common) font size + font_sizes = collections.defaultdict(lambda : 0) + body = root.xpath('//body')[0] + IGNORE = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6') + for elem in body.iter(etree.Element): + if elem.tag not in IGNORE: + t = getattr(elem, 'text', '') + if t: t = t.strip() + if t: + font_sizes[elem.computed_font_size] += len(t) + + t = getattr(elem, 'tail', '') + if t: t = t.strip() + if t: + parent = elem.getparent() + if parent.tag not in IGNORE: + font_sizes[parent.computed_font_size] += len(t) + + try: + most_common = max(font_sizes.items(), key=operator.itemgetter(1))[0] + scale = base/most_common if most_common > 0 else 1. + except ValueError: + scale = 1. + + # rescale absolute line-heights + counter = 0 + for sheet in stylesheets: + for selector, lh in sheet.lh_rules: + for elem in selector(root): + elem.set('id', elem.get('id', 'cfs_%d'%counter)) + counter += 1 + if not extra_css.has_key(elem.get('id')): + extra_css[elem.get('id')] = [] + extra_css[elem.get('id')].append('line-height:%fpt'%(lh*scale)) + + + + # Rescale all computed font sizes + for elem in body.iter(etree.Element): + if isinstance(elem, HtmlElement): + elem.computed_font_size *= scale + + # Remove all font size specifications from the last stylesheet + cls.remove_font_size_information(stylesheets[-1:]) + + # Create the CSS to implement the rescaled font sizes + for elem in body.iter(etree.Element): + cfs, pcfs = map(operator.attrgetter('computed_font_size'), (elem, elem.getparent())) + if abs(cfs-pcfs) > 1/12. and abs(pcfs) > 1/12.: + elem.set('id', elem.get('id', 'cfs_%d'%counter)) + counter += 1 + if not extra_css.has_key(elem.get('id')): + extra_css[elem.get('id')] = [] + extra_css[elem.get('id')].append('font-size: %f%%'%(100*(cfs/pcfs))) + + css = CSSParser(loglevel=logging.ERROR).parseString('') + for id, r in extra_css.items(): + css.add('#%s {%s}'%(id, ';'.join(r))) + return css + + @classmethod + def rationalize(cls, stylesheets, root, opts): + logger = logging.getLogger('html2epub') + logger.info('\t\tRationalizing fonts...') + extra_css = None + if opts.base_font_size2 > 0: + try: + extra_css = cls.compute_font_sizes(root, stylesheets, base=opts.base_font_size2) + except: + logger.warning('Failed to rationalize font sizes.') + if opts.verbose > 1: + logger.exception('') + finally: + root.remove_font_size_information() + logger.debug('\t\tDone rationalizing') + return extra_css + +################################################################################ +############## Testing +################################################################################ + +class FontTest(unittest.TestCase): + + def setUp(self): + from calibre.ebooks.epub import config + self.opts = config(defaults='').parse() + self.html = ''' + + + Test document + + +
+ +

Some text

+
+

Some other text.

+

The longest piece of single font size text in this entire file. Used to test resizing.

+ + + ''' + self.root = fromstring(self.html) + + def do_test(self, css, base=DEFAULT_FONT_SIZE, scale=1): + root1 = copy.deepcopy(self.root) + root1.computed_font_size = DEFAULT_FONT_SIZE + stylesheet = CSSParser(loglevel=logging.ERROR).parseString(css) + stylesheet2 = Rationalizer.compute_font_sizes(root1, [stylesheet], base) + root2 = copy.deepcopy(root1) + root2.remove_font_size_information() + root2.computed_font_size = DEFAULT_FONT_SIZE + Rationalizer.apply_font_size_rules([stylesheet2], root2) + for elem in root2.iter(etree.Element): + Rationalizer.compute_font_size(elem) + for e1, e2 in zip(root1.xpath('//body')[0].iter(etree.Element), root2.xpath('//body')[0].iter(etree.Element)): + self.assertAlmostEqual(e1.computed_font_size, e2.computed_font_size, + msg='Computed font sizes for %s not equal. Original: %f Processed: %f'%\ + (root1.getroottree().getpath(e1), e1.computed_font_size, e2.computed_font_size)) + return stylesheet2.cssText + + def testStripping(self): + 'Test that any original entries are removed from the CSS' + css = 'p { font: bold 10px italic smaller; font-size: x-large} \na { font-size: 0 }' + css = CSSParser(loglevel=logging.ERROR).parseString(css) + Rationalizer.compute_font_sizes(copy.deepcopy(self.root), [css]) + self.assertEqual(css.cssText.replace(' ', '').replace('\n', ''), + 'p{font:bolditalic}') + + def testIdentity(self): + 'Test that no unnecessary font size changes are made' + extra_css = self.do_test('div {font-size:12pt} \nspan {font-size:100%}') + self.assertEqual(extra_css.strip(), '') + + def testRelativization(self): + 'Test conversion of absolute to relative sizes' + self.do_test('#p1 {font: 24pt} b {font: 12pt} .it {font: 48pt} #p2 {font: 100%}') + + def testResizing(self): + 'Test resizing of fonts' + self.do_test('#longest {font: 24pt} .it {font:20pt; line-height:22pt}') + + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(FontTest) + +def test(): + unittest.TextTestRunner(verbosity=2).run(suite()) + +if __name__ == '__main__': + sys.exit(test()) + \ No newline at end of file diff --git a/src/calibre/ebooks/epub/from_any.py b/src/calibre/ebooks/epub/from_any.py new file mode 100644 index 0000000000..e59564cc43 --- /dev/null +++ b/src/calibre/ebooks/epub/from_any.py @@ -0,0 +1,164 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Convert any ebook format to epub. +''' + +import sys, os, re +from contextlib import nested + +from calibre import extract, walk +from calibre.ebooks import DRMError +from calibre.ebooks.epub import config as common_config +from calibre.ebooks.epub.from_html import convert as html2epub, find_html_index +from calibre.ptempfile import TemporaryDirectory +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf2 import OPFCreator +from calibre.utils.zipfile import ZipFile + +def lit2opf(path, tdir, opts): + from calibre.ebooks.lit.reader import LitReader + print 'Exploding LIT file:', path + reader = LitReader(path) + reader.extract_content(tdir, False) + for f in walk(tdir): + if f.lower().endswith('.opf'): + return f + +def mobi2opf(path, tdir, opts): + from calibre.ebooks.mobi.reader import MobiReader + print 'Exploding MOBI file:', path + reader = MobiReader(path) + reader.extract_content(tdir) + files = list(walk(tdir)) + opts.dont_preserve_structure = True + opts.encoding = 'utf-8' + for f in files: + if f.lower().endswith('.opf'): + return f + html_pat = re.compile(r'\.(x){0,1}htm(l){0,1}', re.IGNORECASE) + hf = [f for f in files if html_pat.match(os.path.splitext(f)[1]) is not None] + mi = MetaInformation(os.path.splitext(os.path.basename(path))[0], [_('Unknown')]) + opf = OPFCreator(tdir, mi) + opf.create_manifest([(hf[0], None)]) + opf.create_spine([hf[0]]) + ans = os.path.join(tdir, 'metadata.opf') + opf.render(open(ans, 'wb')) + return ans + +def fb22opf(path, tdir, opts): + from calibre.ebooks.lrf.fb2.convert_from import to_html + print 'Converting FB2 to HTML...' + return to_html(path, tdir) + +def rtf2opf(path, tdir, opts): + from calibre.ebooks.lrf.rtf.convert_from import generate_html + generate_html(path, tdir) + return os.path.join(tdir, 'metadata.opf') + +def txt2opf(path, tdir, opts): + from calibre.ebooks.lrf.txt.convert_from import generate_html + generate_html(path, opts.encoding, tdir) + return os.path.join(tdir, 'metadata.opf') + +def pdf2opf(path, tdir, opts): + from calibre.ebooks.lrf.pdf.convert_from import generate_html + generate_html(path, tdir) + return os.path.join(tdir, 'metadata.opf') + +def epub2opf(path, tdir, opts): + zf = ZipFile(path) + zf.extractall(tdir) + if os.path.exists(os.path.join(tdir, 'META-INF', 'encryption.xml')): + raise DRMError(os.path.basename(path)) + for f in walk(tdir): + if f.lower().endswith('.opf'): + return f + raise ValueError('%s is not a valid EPUB file'%path) + +def odt2epub(path, tdir, opts): + from calibre.ebooks.odt.to_oeb import Extract + opts.encoding = 'utf-8' + return Extract()(path, tdir) + +MAP = { + 'lit' : lit2opf, + 'mobi' : mobi2opf, + 'prc' : mobi2opf, + 'fb2' : fb22opf, + 'rtf' : rtf2opf, + 'txt' : txt2opf, + 'pdf' : pdf2opf, + 'epub' : epub2opf, + 'odt' : odt2epub, + } +SOURCE_FORMATS = ['lit', 'mobi', 'prc', 'fb2', 'odt', 'rtf', 'txt', 'pdf', 'rar', 'zip', 'oebzip', 'htm', 'html', 'epub'] + +def unarchive(path, tdir): + extract(path, tdir) + files = list(walk(tdir)) + + for ext in ['opf'] + list(MAP.keys()): + for f in files: + if f.lower().endswith('.'+ext): + if ext in ['txt', 'rtf'] and os.stat(f).st_size < 2048: + continue + return f, ext + return find_html_index(files) + +def any2epub(opts, path, notification=None): + ext = os.path.splitext(path)[1] + if not ext: + raise ValueError('Unknown file type: '+path) + ext = ext.lower()[1:] + + if opts.output is None: + opts.output = os.path.splitext(os.path.basename(path))[0]+'.epub' + + with nested(TemporaryDirectory('_any2epub1'), TemporaryDirectory('_any2epub2')) as (tdir1, tdir2): + if ext in ['rar', 'zip', 'oebzip']: + path, ext = unarchive(path, tdir1) + print 'Found %s file in archive'%(ext.upper()) + + if ext in MAP.keys(): + path = MAP[ext](path, tdir2, opts) + ext = 'opf' + + + if re.match(r'((x){0,1}htm(l){0,1})|opf', ext) is None: + raise ValueError('Conversion from %s is not supported'%ext.upper()) + + print 'Creating EPUB file...' + html2epub(path, opts, notification=notification) + +def config(defaults=None): + return common_config(defaults=defaults) + + +def formats(): + return ['html', 'rar', 'zip', 'oebzip']+list(MAP.keys()) + +def option_parser(): + + return config().option_parser(usage=_('''\ +%%prog [options] filename + +Convert any of a large number of ebook formats to an epub file. Supported formats are: %s +''')%formats() +) + +def main(args=sys.argv): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) < 2: + parser.print_help() + print 'No input file specified.' + return 1 + any2epub(opts, args[1]) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/epub/from_comic.py b/src/calibre/ebooks/epub/from_comic.py new file mode 100644 index 0000000000..c6dff349da --- /dev/null +++ b/src/calibre/ebooks/epub/from_comic.py @@ -0,0 +1,21 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +'Convert a comic in CBR/CBZ format to epub' + +import sys +from functools import partial +from calibre.ebooks.lrf.comic.convert_from import do_convert, option_parser, config, main as _main + +convert = partial(do_convert, output_format='epub') +main = partial(_main, output_format='epub') + +if __name__ == '__main__': + sys.exit(main()) + +if False: + option_parser + config + \ No newline at end of file diff --git a/src/calibre/ebooks/epub/from_feeds.py b/src/calibre/ebooks/epub/from_feeds.py new file mode 100644 index 0000000000..bbadbc54de --- /dev/null +++ b/src/calibre/ebooks/epub/from_feeds.py @@ -0,0 +1,69 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Convert periodical content into EPUB ebooks. +''' +import sys, glob, os +from calibre.web.feeds.main import config as feeds2disk_config, USAGE, run_recipe +from calibre.ebooks.epub.from_html import config as html2epub_config +from calibre.ptempfile import TemporaryDirectory +from calibre.ebooks.epub.from_html import convert as html2epub +from calibre import strftime, sanitize_file_name + +def config(defaults=None): + c = feeds2disk_config(defaults=defaults) + c.remove('lrf') + c.remove('epub') + c.remove('output_dir') + c.update(html2epub_config(defaults=defaults)) + c.remove('chapter_mark') + return c + +def option_parser(): + c = config() + return c.option_parser(usage=USAGE) + +def convert(opts, recipe_arg, notification=None): + opts.lrf = False + opts.epub = True + if opts.debug: + opts.verbose = 2 + parser = option_parser() + with TemporaryDirectory('_feeds2epub') as tdir: + opts.output_dir = tdir + recipe = run_recipe(opts, recipe_arg, parser, notification=notification) + c = config() + recipe_opts = c.parse_string(recipe.html2epub_options) + c.smart_update(recipe_opts, opts) + opts = recipe_opts + opts.chapter_mark = 'none' + opf = glob.glob(os.path.join(tdir, '*.opf')) + if not opf: + raise Exception('Downloading of recipe: %s failed'%recipe_arg) + opf = opf[0] + + if opts.output is None: + fname = recipe.title + strftime(recipe.timefmt) + '.epub' + opts.output = os.path.join(os.getcwd(), sanitize_file_name(fname)) + + print 'Generating epub...' + opts.encoding = 'utf-8' + html2epub(opf, opts, notification=notification) + + +def main(args=sys.argv, notification=None, handler=None): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) != 2 and opts.feeds is None: + parser.print_help() + return 1 + recipe_arg = args[1] if len(args) > 1 else None + convert(opts, recipe_arg, notification=notification) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/src/calibre/ebooks/epub/from_html.py b/src/calibre/ebooks/epub/from_html.py new file mode 100644 index 0000000000..a86ca794a4 --- /dev/null +++ b/src/calibre/ebooks/epub/from_html.py @@ -0,0 +1,314 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Conversion of HTML/OPF files follows several stages: + + * All links in the HTML files or in the OPF manifest are + followed to build up a list of HTML files to be converted. + This stage is implemented by + :function:`calibre.ebooks.html.traverse` and + :class:`calibre.ebooks.html.HTMLFile`. + + * The HTML is pre-processed to make it more semantic. + All links in the HTML files to other resources like images, + stylesheets, etc. are relativized. The resources are copied + into the `resources` sub directory. This is accomplished by + :class:`calibre.ebooks.html.PreProcessor` and + :class:`calibre.ebooks.html.Parser`. + + * The HTML is processed. Various operations are performed. + All style declarations are extracted and consolidated into + a single style sheet. Chapters are auto-detected and marked. + Various font related manipulations are performed. See + :class:`HTMLProcessor`. + + * The processed HTML is saved and the + :module:`calibre.ebooks.epub.split` module is used to split up + large HTML files into smaller chunks. + + * The EPUB container is created. +''' + +import os, sys, cStringIO, logging, re + +from lxml.etree import XPath +try: + from PIL import Image as PILImage +except ImportError: + import Image as PILImage + +from calibre.ebooks.html import Processor, merge_metadata, get_filelist,\ + opf_traverse, create_metadata, rebase_toc +from calibre.ebooks.epub import config as common_config +from calibre.ptempfile import TemporaryDirectory +from calibre.ebooks.metadata import MetaInformation +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.fonts import Rationalizer +from calibre.constants import preferred_encoding +from calibre import walk + +def find_html_index(files): + ''' + Given a list of files, find the most likely root HTML file in the + list. + ''' + html_pat = re.compile(r'\.(x){0,1}htm(l){0,1}$', re.IGNORECASE) + html_files = [f for f in files if html_pat.search(f) is not None] + if not html_files: + raise ValueError(_('Could not find an ebook inside the archive')) + html_files = [(f, os.stat(f).st_size) for f in html_files] + html_files.sort(cmp = lambda x, y: cmp(x[1], y[1])) + html_files = [f[0] for f in html_files] + for q in ('toc', 'index'): + for f in html_files: + if os.path.splitext(f)[0].lower() == q: + return f, os.path.splitext(f)[1].lower()[1:] + return html_files[-1], os.path.splitext(html_files[-1])[1].lower()[1:] + +class HTMLProcessor(Processor, Rationalizer): + + def __init__(self, htmlfile, opts, tdir, resource_map, htmlfiles, stylesheets): + Processor.__init__(self, htmlfile, opts, tdir, resource_map, htmlfiles, + name='html2epub') + if opts.verbose > 2: + self.debug_tree('parsed') + self.detect_chapters() + + self.extract_css(stylesheets) + if self.opts.base_font_size2 > 0: + self.font_css = self.rationalize(self.external_stylesheets+[self.stylesheet], + self.root, self.opts) + if opts.verbose > 2: + self.debug_tree('nocss') + + def save(self): + for meta in list(self.root.xpath('//meta')): + meta.getparent().remove(meta) + Processor.save(self) + + + + +def config(defaults=None): + return common_config(defaults=defaults) + +def option_parser(): + c = config() + return c.option_parser(usage=_('''\ +%prog [options] file.html|opf + +Convert a HTML file to an EPUB ebook. Recursively follows links in the HTML file. +If you specify an OPF file instead of an HTML file, the list of links is takes from +the element of the OPF file. +''')) + +def parse_content(filelist, opts, tdir): + os.makedirs(os.path.join(tdir, 'content', 'resources')) + resource_map, stylesheets = {}, {} + toc = TOC(base_path=tdir, type='root') + stylesheet_map = {} + for htmlfile in filelist: + logging.getLogger('html2epub').debug('Processing %s...'%htmlfile) + hp = HTMLProcessor(htmlfile, opts, os.path.join(tdir, 'content'), + resource_map, filelist, stylesheets) + hp.populate_toc(toc) + hp.save() + stylesheet_map[os.path.basename(hp.save_path())] = \ + [s for s in hp.external_stylesheets + [hp.stylesheet, hp.font_css, hp.override_css] if s is not None] + + logging.getLogger('html2epub').debug('Saving stylesheets...') + if opts.base_font_size2 > 0: + Rationalizer.remove_font_size_information(stylesheets.values()) + for path, css in stylesheets.items(): + open(path, 'wb').write(getattr(css, 'cssText', css).encode('utf-8')) + if toc.count('chapter') > opts.toc_threshold: + toc.purge(['file', 'link', 'unknown']) + if toc.count('chapter') + toc.count('file') > opts.toc_threshold: + toc.purge(['link', 'unknown']) + toc.purge(['link'], max=opts.max_toc_links) + + return resource_map, hp.htmlfile_map, toc, stylesheet_map + +def resize_cover(im, opts): + width, height = im.size + dw, dh = (opts.profile.screen_size[0]-width)/float(width), (opts.profile.screen_size[1]-height)/float(height) + delta = min(dw, dh) + if delta > 0: + nwidth = int(width + delta*(width)) + nheight = int(height + delta*(height)) + im = im.resize((int(nwidth), int(nheight)), PILImage.ANTIALIAS).convert('RGB') + return im + +def process_title_page(mi, filelist, htmlfilemap, opts, tdir): + old_title_page = None + f = lambda x : os.path.normcase(os.path.normpath(x)) + if mi.cover: + if f(filelist[0].path) == f(mi.cover): + old_title_page = htmlfilemap[filelist[0].path] + + #logger = logging.getLogger('html2epub') + metadata_cover = mi.cover + if metadata_cover and not os.path.exists(metadata_cover): + metadata_cover = None + if metadata_cover is not None: + with open(metadata_cover, 'rb') as src: + try: + im = PILImage.open(src) + if opts.profile.screen_size is not None: + im = resize_cover(im, opts) + metadata_cover = im + except: + metadata_cover = None + + specified_cover = opts.cover + if specified_cover and not os.path.exists(specified_cover): + specified_cover = None + if specified_cover is not None: + with open(specified_cover, 'rb') as src: + try: + im = PILImage.open(src) + if opts.profile.screen_size is not None: + im = resize_cover(im, opts) + specified_cover = im + except: + specified_cover = None + + cover = metadata_cover if specified_cover is None or (opts.prefer_metadata_cover and metadata_cover is not None) else specified_cover + if hasattr(cover, 'save'): + cpath = '/'.join(('resources', '_cover_.jpg')) + cover_dest = os.path.join(tdir, 'content', *cpath.split('/')) + with open(cover_dest, 'wb') as f: + im.save(f, format='jpeg') + titlepage = '''\ + + + Cover + + + +
+ cover +
+ + + '''%cpath + tp = 'calibre_title_page.html' if old_title_page is None else old_title_page + tppath = os.path.join(tdir, 'content', tp) + with open(tppath, 'wb') as f: + f.write(titlepage) + return tp if old_title_page is None else None, True + + return None, old_title_page is not None + + +def convert(htmlfile, opts, notification=None): + htmlfile = os.path.abspath(htmlfile) + if opts.output is None: + opts.output = os.path.splitext(os.path.basename(htmlfile))[0] + '.epub' + opts.profile = PROFILES[opts.profile] + opts.output = os.path.abspath(opts.output) + if opts.override_css is not None: + try: + opts.override_css = open(opts.override_css, 'rb').read().decode(preferred_encoding, 'replace') + except: + opts.override_css = opts.override_css.decode(preferred_encoding, 'replace') + if htmlfile.lower().endswith('.opf'): + opf = OPF(htmlfile, os.path.dirname(os.path.abspath(htmlfile))) + filelist = opf_traverse(opf, verbose=opts.verbose, encoding=opts.encoding) + if not filelist: + # Bad OPF look for a HTML file instead + htmlfile = find_html_index(walk(os.path.dirname(htmlfile)))[0] + if htmlfile is None: + raise ValueError('Could not find suitable file to convert.') + filelist = get_filelist(htmlfile, opts)[1] + mi = MetaInformation(opf) + else: + opf, filelist = get_filelist(htmlfile, opts) + mi = merge_metadata(htmlfile, opf, opts) + opts.chapter = XPath(opts.chapter, + namespaces={'re':'http://exslt.org/regular-expressions'}) + if opts.level1_toc: + opts.level1_toc = XPath(opts.level1_toc, + namespaces={'re':'http://exslt.org/regular-expressions'}) + else: + opts.level1_toc = None + if opts.level2_toc: + opts.level2_toc = XPath(opts.level2_toc, + namespaces={'re':'http://exslt.org/regular-expressions'}) + else: + opts.level2_toc = None + + with TemporaryDirectory(suffix='_html2epub', keep=opts.keep_intermediate) as tdir: + if opts.keep_intermediate: + print 'Intermediate files in', tdir + resource_map, htmlfile_map, generated_toc, stylesheet_map = \ + parse_content(filelist, opts, tdir) + logger = logging.getLogger('html2epub') + resources = [os.path.join(tdir, 'content', f) for f in resource_map.values()] + + + title_page, has_title_page = process_title_page(mi, filelist, htmlfile_map, opts, tdir) + spine = [htmlfile_map[f.path] for f in filelist] + if title_page is not None: + spine = [title_page] + spine + mi.cover = None + mi.cover_data = (None, None) + + + mi = create_metadata(tdir, mi, spine, resources) + buf = cStringIO.StringIO() + if mi.toc: + rebase_toc(mi.toc, htmlfile_map, tdir) + if opts.use_auto_toc or mi.toc is None or len(list(mi.toc.flat())) < 2: + mi.toc = generated_toc + if opts.from_ncx: + toc = TOC() + toc.read_ncx_toc(opts.from_ncx) + mi.toc = toc + for item in mi.manifest: + if getattr(item, 'mime_type', None) == 'text/html': + item.mime_type = 'application/xhtml+xml' + opf_path = os.path.join(tdir, 'metadata.opf') + with open(opf_path, 'wb') as f: + mi.render(f, buf, 'toc.ncx') + toc = buf.getvalue() + if toc: + with open(os.path.join(tdir, 'toc.ncx'), 'wb') as f: + f.write(toc) + if opts.show_ncx: + print toc + split(opf_path, opts, stylesheet_map) + opf = OPF(opf_path, tdir) + opf.remove_guide() + if has_title_page: + opf.create_guide_element() + opf.add_guide_item('cover', 'Cover', 'content/'+spine[0]) + with open(opf_path, 'wb') as f: + f.write(opf.render()) + epub = initialize_container(opts.output) + epub.add_dir(tdir) + if opts.show_opf: + print open(os.path.join(tdir, 'metadata.opf')).read() + logger.info('Output written to %s'%opts.output) + if opts.extract_to is not None: + epub.extractall(opts.extract_to) + + +def main(args=sys.argv): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) < 2: + parser.print_help() + print _('You must specify an input HTML file') + return 1 + convert(args[1], opts) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/epub/split.py b/src/calibre/ebooks/epub/split.py new file mode 100644 index 0000000000..1cdb97ec7c --- /dev/null +++ b/src/calibre/ebooks/epub/split.py @@ -0,0 +1,405 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Split the flows in an epub file to conform to size limitations. +''' + +import os, math, logging, functools, collections, re, copy + +from lxml.etree import XPath as _XPath +from lxml import etree, html +from lxml.cssselect import CSSSelector + +from calibre.ebooks.metadata.opf2 import OPF +from calibre.ebooks.epub import tostring, rules +from calibre import CurrentDir, LoggingInterface + +XPath = functools.partial(_XPath, namespaces={'re':'http://exslt.org/regular-expressions'}) +content = functools.partial(os.path.join, 'content') + +SPLIT_ATTR = 'cs' +SPLIT_POINT_ATTR = 'csp' + +class SplitError(ValueError): + + def __init__(self, path, root): + size = len(tostring(root))/1024. + ValueError.__init__(self, _('Could not find reasonable point at which to split: %s Sub-tree size: %d KB')% + (os.path.basename(path), size)) + + + +class Splitter(LoggingInterface): + + def __init__(self, path, opts, stylesheet_map, always_remove=False): + LoggingInterface.__init__(self, logging.getLogger('htmlsplit')) + self.setup_cli_handler(opts.verbose) + self.path = path + self.always_remove = always_remove + self.base = (os.path.splitext(path)[0].replace('%', '%%') + '_split_%d.html') + self.opts = opts + self.orig_size = os.stat(content(path)).st_size + self.log_info('\tSplitting %s (%d KB)', path, self.orig_size/1024.) + root = html.fromstring(open(content(path)).read()) + + self.page_breaks = [] + self.find_page_breaks(stylesheet_map[self.path], root) + + self.trees = [] + self.split_size = 0 + self.split(root.getroottree()) + self.commit() + self.log_info('\t\tSplit into %d parts.', len(self.trees)) + if self.opts.verbose: + for f in self.files: + self.log_info('\t\t\t%s - %d KB', f, os.stat(content(f)).st_size/1024.) + self.trees = None + + def split_text(self, text, root, size): + self.log_debug('\t\t\tSplitting text of length: %d'%len(text)) + rest = text.replace('\r', '') + parts = re.split('\n\n', rest) + self.log_debug('\t\t\t\tFound %d parts'%len(parts)) + if max(map(len, parts)) > size: + raise SplitError('Cannot split as file contains a
 tag with a very large paragraph', root) 
+        ans = []
+        buf = ''
+        for part in parts:
+            if len(buf) + len(part) < size:
+                buf += '\n\n'+part
+            else:
+                ans.append(buf)
+                buf = part
+        return ans
+            
+    
+    def split(self, tree):
+        '''
+        Split ``tree`` into a *before* and *after* tree, preserving tag structure,
+        but not duplicating any text. All tags that have had their text and tail
+        removed have the attribute ``calibre_split`` set to 1.
+        '''
+        self.log_debug('\t\tSplitting...')
+        root = tree.getroot()
+        # Split large 
 tags
+        for pre in list(root.xpath('//pre')):
+            text = u''.join(pre.xpath('./text()'))
+            pre.text = text
+            for child in list(pre.iterdescendants()):
+                pre.remove(child)
+            if len(pre.text) > self.opts.profile.flow_size*0.5:
+                frags = self.split_text(pre.text, root, int(0.2*self.opts.profile.flow_size))
+                new_pres = []
+                for frag in frags:
+                    pre2 = copy.copy(pre)
+                    pre2.text = frag
+                    pre2.tail = u''
+                    new_pres.append(pre2)
+                new_pres[-1].tail = pre.tail
+                p = pre.getparent()
+                i = p.index(pre)
+                p[i:i+1] = new_pres
+        
+        split_point, before = self.find_split_point(root)
+        if split_point is None or self.split_size > 6*self.orig_size:
+            if not self.always_remove:
+                self.log_warn(_('\t\tToo much markup. Re-splitting without structure preservation. This may cause incorrect rendering.'))
+            raise SplitError(self.path, root)
+        tree2 = copy.deepcopy(tree)
+        root2 = tree2.getroot()
+        body, body2 = root.body, root2.body
+        path = tree.getpath(split_point)
+        split_point2 = root2.xpath(path)[0]
+        
+        def nix_element(elem, top=True):
+            if self.always_remove:
+                parent = elem.getparent()
+                index = parent.index(elem)
+                if top:
+                    parent.remove(elem)
+                else:
+                    index = parent.index(elem)
+                    parent[index:index+1] = list(elem.iterchildren())
+                
+            else:
+                elem.text = u''
+                elem.tail = u''
+                elem.set(SPLIT_ATTR, '1')
+                if elem.tag.lower() in ['ul', 'ol', 'dl', 'table', 'hr', 'img']:
+                    elem.set('style', 'display:none;')
+        
+        def fix_split_point(sp):
+            sp.set('style', sp.get('style', '')+'page-break-before:avoid;page-break-after:avoid') 
+        
+        # Tree 1
+        hit_split_point = False
+        for elem in list(body.iterdescendants(etree.Element)):
+            if elem.get(SPLIT_ATTR, '0') == '1':
+                continue
+            if elem is split_point:
+                hit_split_point = True
+                if before:
+                    nix_element(elem)
+                fix_split_point(elem)
+                continue
+            if hit_split_point:
+                nix_element(elem)
+            
+            
+        # Tree 2
+        hit_split_point = False
+        for elem in list(body2.iterdescendants(etree.Element)):
+            if elem.get(SPLIT_ATTR, '0') == '1':
+                continue
+            if elem is split_point2:
+                hit_split_point = True
+                if not before:
+                    nix_element(elem, top=False)
+                fix_split_point(elem)
+                continue
+            if not hit_split_point:
+                nix_element(elem, top=False)
+        
+        for t, r in [(tree, root), (tree2, root2)]:
+            size = len(tostring(r)) 
+            if size <= self.opts.profile.flow_size:
+                self.trees.append(t)
+                #print tostring(t.getroot(), pretty_print=True)
+                self.log_debug('\t\t\tCommitted sub-tree #%d (%d KB)', len(self.trees), size/1024.)
+                self.split_size += size
+            else:
+                self.split(t)
+                
+                
+    def find_page_breaks(self, stylesheets, root):
+        '''
+        Find all elements that have either page-break-before or page-break-after set.
+        '''
+        page_break_selectors = set([])
+        for rule in rules(stylesheets):
+            before = getattr(rule.style.getPropertyCSSValue('page-break-before'), 'cssText', '').strip().lower()
+            after  = getattr(rule.style.getPropertyCSSValue('page-break-after'), 'cssText', '').strip().lower()
+            try:
+                if before and before != 'avoid':
+                    page_break_selectors.add((CSSSelector(rule.selectorText), True))
+            except:
+                pass
+            try:
+                if after and after != 'avoid':
+                    page_break_selectors.add((CSSSelector(rule.selectorText), False))
+            except:
+                pass
+            
+        page_breaks = set([])
+        for selector, before in page_break_selectors:
+            for elem in selector(root):
+                elem.pb_before = before
+                page_breaks.add(elem)
+                
+        for i, elem in enumerate(root.iter()):
+            elem.pb_order = i
+            
+        page_breaks = list(page_breaks)
+        page_breaks.sort(cmp=lambda x,y : cmp(x.pb_order, y.pb_order))
+        for i, x in enumerate(page_breaks):
+            x.set('id', x.get('id', 'calibre_pb_%d'%i))
+            self.page_breaks.append((XPath('//*[@id="%s"]'%x.get('id')), x.pb_before))
+        
+        
+    def find_split_point(self, root):
+        '''
+        Find the tag at which to split the tree rooted at `root`. 
+        Search order is:
+            * page breaks
+            * Heading tags
+            * 
tags + *

tags + + We try to split in the "middle" of the file (as defined by tag counts. + ''' + def pick_elem(elems): + if elems: + elems = [i for i in elems if i.get(SPLIT_POINT_ATTR, '0') != '1'\ + and i.get(SPLIT_ATTR, '0') != '1'] + if elems: + i = int(math.floor(len(elems)/2.)) + elems[i].set(SPLIT_POINT_ATTR, '1') + return elems[i] + + page_breaks = [] + for x in self.page_breaks: + pb = x[0](root) + if pb: + page_breaks.append(pb[0]) + + elem = pick_elem(page_breaks) + if elem is not None: + i = page_breaks.index(elem) + return elem, self.page_breaks[i][1] + + + + for path in ( + '//*[re:match(name(), "h[1-6]", "i")]', + '/html/body/div', + '//pre', + '//hr', + '//p', + '//br', + ): + elems = root.xpath(path) + elem = pick_elem(elems) + if elem is not None: + try: + XPath(elem.getroottree().getpath(elem)) + except: + continue + return elem, True + + return None, True + + def commit(self): + ''' + Commit all changes caused by the split. This removes the previously + introduced ``calibre_split`` attribute and calculates an *anchor_map* for + all anchors in the original tree. Internal links are re-directed. The + original file is deleted and the split files are saved. + ''' + self.anchor_map = collections.defaultdict(lambda :self.base%0) + self.files = [] + + for i, tree in enumerate(self.trees): + root = tree.getroot() + self.files.append(self.base%i) + for elem in root.xpath('//*[@id]'): + if elem.get(SPLIT_ATTR, '0') == '0': + self.anchor_map[elem.get('id')] = self.files[-1] + for elem in root.xpath('//*[@%s or @%s]'%(SPLIT_ATTR, SPLIT_POINT_ATTR)): + elem.attrib.pop(SPLIT_ATTR, None) + elem.attrib.pop(SPLIT_POINT_ATTR, '0') + + for current, tree in zip(self.files, self.trees): + for a in tree.getroot().xpath('//a[@href]'): + href = a.get('href').strip() + if href.startswith('#'): + anchor = href[1:] + file = self.anchor_map[anchor] + if file != current: + a.set('href', file+href) + open(content(current), 'wb').\ + write(tostring(tree.getroot(), pretty_print=self.opts.pretty_print)) + + os.remove(content(self.path)) + + + def fix_opf(self, opf): + ''' + Fix references to the split file in the OPF. + ''' + items = [item for item in opf.itermanifest() if item.get('href') == 'content/'+self.path] + new_items = [('content/'+f, None) for f in self.files] + id_map = {} + for item in items: + id_map[item.get('id')] = opf.replace_manifest_item(item, new_items) + + for id in id_map.keys(): + opf.replace_spine_items_by_idref(id, id_map[id]) + + for ref in opf.iterguide(): + href = ref.get('href', '') + if href.startswith('content/'+self.path): + href = href.split('#') + frag = None + if len(href) > 1: + frag = href[1] + new_file = self.anchor_map[frag] + ref.set('href', 'content/'+new_file+('' if frag is None else ('#'+frag))) + + + +def fix_content_links(html_files, changes, opts): + split_files = [f.path for f in changes] + anchor_maps = [f.anchor_map for f in changes] + files = list(html_files) + for j, f in enumerate(split_files): + try: + i = files.index(f) + files[i:i+1] = changes[j].files + except ValueError: + continue + + for htmlfile in files: + changed = False + root = html.fromstring(open(content(htmlfile), 'rb').read()) + for a in root.xpath('//a[@href]'): + href = a.get('href') + if not href.startswith('#'): + href = href.split('#') + anchor = href[1] if len(href) > 1 else None + href = href[0] + if href in split_files: + newf = anchor_maps[split_files.index(href)][anchor] + frag = ('#'+anchor) if anchor else '' + a.set('href', newf+frag) + changed = True + + if changed: + open(content(htmlfile), 'wb').write(tostring(root, pretty_print=opts.pretty_print)) + +def fix_ncx(path, changes): + split_files = [f.path for f in changes] + anchor_maps = [f.anchor_map for f in changes] + tree = etree.parse(path) + changed = False + for content in tree.getroot().xpath('//x:content[@src]', namespaces={'x':"http://www.daisy.org/z3986/2005/ncx/"}): + href = content.get('src') + if not href.startswith('#'): + href = href.split('#') + anchor = href[1] if len(href) > 1 else None + href = href[0].split('/')[-1] + if href in split_files: + newf = anchor_maps[split_files.index(href)][anchor] + frag = ('#'+anchor) if anchor else '' + content.set('src', 'content/'+newf+frag) + changed = True + if changed: + open(path, 'wb').write(etree.tostring(tree.getroot(), encoding='UTF-8', xml_declaration=True)) + +def split(pathtoopf, opts, stylesheet_map): + pathtoopf = os.path.abspath(pathtoopf) + with CurrentDir(os.path.dirname(pathtoopf)): + opf = OPF(open(pathtoopf, 'rb'), os.path.dirname(pathtoopf)) + html_files = [] + for item in opf.itermanifest(): + if 'html' in item.get('media-type', '').lower(): + f = item.get('href').split('/')[-1] + f2 = f.replace('&', '%26') + if not os.path.exists(content(f)) and os.path.exists(content(f2)): + f = f2 + item.set('href', item.get('href').replace('&', '%26')) + html_files.append(f) + changes = [] + always_remove = getattr(opts, 'dont_preserve_structure', False) + for f in html_files: + if os.stat(content(f)).st_size > opts.profile.flow_size: + try: + changes.append(Splitter(f, opts, stylesheet_map, + always_remove=(always_remove or \ + os.stat(content(f)).st_size > 5*opts.profile.flow_size))) + except (SplitError, RuntimeError): + if not always_remove: + changes.append(Splitter(f, opts, stylesheet_map, always_remove=True)) + else: + raise + changes[-1].fix_opf(opf) + + open(pathtoopf, 'wb').write(opf.render()) + fix_content_links(html_files, changes, opts) + + for item in opf.itermanifest(): + if item.get('media-type', '') == 'application/x-dtbncx+xml': + fix_ncx(item.get('href'), changes) + break diff --git a/src/calibre/ebooks/epub/traverse.py b/src/calibre/ebooks/epub/traverse.py deleted file mode 100644 index d5d019f376..0000000000 --- a/src/calibre/ebooks/epub/traverse.py +++ /dev/null @@ -1,199 +0,0 @@ -from __future__ import with_statement -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' -__docformat__ = 'restructuredtext en' - -''' -Recursively parse HTML files to find all linked files. See :function:`traverse`. -''' - -import sys, os, re -from urlparse import urlparse -from urllib import unquote -from calibre import unicode_path -from calibre.ebooks.chardet import xml_to_unicode - -class Link(object): - ''' - Represents a link in a HTML file. - ''' - - @classmethod - def url_to_local_path(cls, url, base): - path = url.path - if os.path.isabs(path): - return path - return os.path.abspath(os.path.join(base, path)) - - def __init__(self, url, base): - ''' - :param url: The url this link points to. Must be an unquoted unicode string. - :param base: The base directory that relative URLs are with respect to. - Must be a unicode string. - ''' - assert isinstance(url, unicode) and isinstance(base, unicode) - self.url = url - self.parsed_url = urlparse(unquote(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 - if self.is_local and not self.is_internal: - self.path = self.url_to_local_path(self.parsed_url, base) - - def __hash__(self): - if self.path is None: - return hash(self.url) - return hash(self.path) - - def __eq__(self, other): - return self.path == getattr(other, 'path', other) - - def __str__(self): - return u'Link: %s --> %s'%(self.url, self.path) - - -class IgnoreFile(Exception): - - def __init__(self, msg, errno): - Exception.__init__(self, msg) - self.doesnt_exist = errno == 2 - self.errno = errno - -class HTMLFile(object): - ''' - Contains basic information about an HTML file. This - includes a list of links to other files as well as - the encoding of each file. Also tries to detect if the file is not a HTML - file in which case :member:`is_binary` is set to True. - - The encoding of the file is available as :member:`encoding`. - ''' - - HTML_PAT = re.compile(r'<\s*html', re.IGNORECASE) - LINK_PAT = re.compile( - r'<\s*a\s+.*?href\s*=\s*(?:(?:"(?P[^"]+)")|(?:\'(?P[^\']+)\')|(?P[^\s]+))', - re.DOTALL|re.IGNORECASE) - - def __init__(self, path_to_html_file, level, encoding, verbose): - ''' - :param level: The level of this file. Should be 0 for the root file. - :param encoding: Use `encoding` to decode HTML. - ''' - self.path = unicode_path(path_to_html_file, abs=True) - self.base = os.path.dirname(self.path) - self.level = level - self.links = [] - - try: - with open(self.path, 'rb') as f: - src = f.read() - except IOError, err: - msg = 'Could not read from file: %s with error: %s'%(self.path, unicode(err)) - if level == 0: - raise IOError(msg) - raise IgnoreFile(msg, err.errno) - - self.is_binary = not bool(self.HTML_PAT.search(src[:1024])) - - if not self.is_binary: - if encoding is None: - encoding = xml_to_unicode(src[:4096], verbose=verbose)[-1] - self.encoding = encoding - - src = src.decode(encoding, 'replace') - self.find_links(src) - - - - def __eq__(self, other): - return self.path == getattr(other, 'path', other) - - def __str__(self): - return u'HTMLFile:%d:%s:%s'%(self.level, 'b' if self.is_binary else 'a', self.path) - - def __repr__(self): - return str(self) - - - def find_links(self, src): - for match in self.LINK_PAT.finditer(src): - url = None - for i in ('url1', 'url2', 'url3'): - url = match.group(i) - if url: - break - link = Link(url, self.base) - if link not in self.links: - self.links.append(link) - - -def depth_first(root, flat, visited=set([])): - yield root - visited.add(root) - for link in root.links: - if link.path is not None and link not in visited: - try: - index = flat.index(link) - except ValueError: # Can happen if max_levels is used - continue - hf = flat[index] - if hf not in visited: - yield hf - visited.add(hf) - for hf in depth_first(hf, flat, visited): - if hf not in visited: - yield hf - visited.add(hf) - - -def traverse(path_to_html_file, max_levels=sys.maxint, verbose=0, encoding=None): - ''' - Recursively traverse all links in the HTML file. - - :param max_levels: Maximum levels of recursion. Must be non-negative. 0 - implies that no links in hte root HTML file are followed. - :param encoding: Specify character encoding of HTML files. If `None` it is - auto-detected. - :return: A pair of lists (breadth_first, depth_first). Each list contains - :class:`HTMLFile` objects. - ''' - assert max_levels >= 0 - level = 0 - flat = [HTMLFile(path_to_html_file, level, encoding, verbose)] - next_level = list(flat) - while level < max_levels and len(next_level) > 0: - level += 1 - nl = [] - for hf in next_level: - rejects = [] - for link in hf.links: - if link.path is None or link.path in flat: - continue - try: - nf = HTMLFile(link.path, level, encoding, verbose) - nl.append(nf) - flat.append(nf) - except IgnoreFile, err: - rejects.append(link) - if not err.doesnt_exist or verbose > 1: - print str(err) - for link in rejects: - hf.links.remove(link) - - next_level = list(nl) - - return flat, list(depth_first(flat[0], flat)) - - - - - - -if __name__ == '__main__': - breadth_first, depth_first = traverse(sys.argv[1], verbose=2) - print 'Breadth first...' - for f in breadth_first: print f - print '\n\nDepth first...' - for f in depth_first: print f - diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py new file mode 100644 index 0000000000..ea968edd53 --- /dev/null +++ b/src/calibre/ebooks/html.py @@ -0,0 +1,1020 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Code to recursively parse HTML files and create an open ebook in a specified +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 urllib import unquote + +from lxml import etree +from lxml.html import HtmlElementClassLookup, HTMLParser as _HTMLParser, \ + fromstring as _fromstring, tostring as _tostring, \ + soupparser, HtmlElement +from lxml.etree import XPath +get_text = XPath("//text()") + +from calibre import LoggingInterface, unicode_path, entity_to_unicode +from calibre.ebooks.chardet import xml_to_unicode, ENCODING_PATS +from calibre.utils.config import Config, StringConfig +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.meta import get_metadata +from calibre.ebooks.metadata.opf2 import OPF, OPFCreator +from calibre.ptempfile import PersistentTemporaryDirectory, PersistentTemporaryFile +from calibre.utils.zipfile import ZipFile +from cssutils import CSSParser + +class HTMLElement(HtmlElement): + + @apply + def specified_font_size(): + + def fget(self): + ans = self.get('specified_font_size', '') + if not ans: + return lambda x: x + if ans.startswith('f'): + return functools.partial(operator.mul, float(ans[1:])) + return float(ans) + + def fset(self, val): + self.set('specified_font_size', ('f'+repr(val(1))) if callable(val) else repr(val)) + + return property(fget=fget, fset=fset) + + @apply + def computed_font_size(): + def fget(self): + ans = self.get('computed_font_size', '') + if ans == '': + return None + return float(ans) + + def fset(self, val): + self.set('computed_font_size', repr(val)) + + return property(fget=fget, fset=fset) + + def remove_font_size_information(self): + for elem in self.iter(): + for p in ('computed', 'specified'): + elem.attrib.pop(p+'_font_size', None) + + def getpath(self): + return self.getroottree().getpath(self) + +class Lookup(HtmlElementClassLookup): + + def lookup(self, node_type, document, namespace, name): + if node_type == 'element': + return HTMLElement + return HtmlElementClassLookup.lookup(self, node_type, document, namespace, name) + +class HTMLParser(_HTMLParser): + + def __init__(self, **kwargs): + super(HTMLParser, self).__init__(**kwargs) + self.set_element_class_lookup(Lookup()) + +parser = HTMLParser() + +def fromstring(raw, **kw): + return _fromstring(raw, parser=parser, **kw) + +def tostring(root, pretty_print=False): + return _tostring(root, encoding='utf-8', method='xml', + include_meta_content_type=True, + pretty_print=pretty_print) + +class Link(object): + ''' + Represents a link in a HTML file. + ''' + + @classmethod + def url_to_local_path(cls, url, base): + path = url.path + if os.path.isabs(path): + return path + return os.path.abspath(os.path.join(base, path)) + + def __init__(self, url, base): + ''' + :param url: The url this link points to. Must be an unquoted unicode string. + :param base: The base directory that relative URLs are with respect to. + Must be a unicode string. + ''' + assert isinstance(url, unicode) and isinstance(base, unicode) + self.url = url + self.parsed_url = urlparse(unquote(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 + if self.is_local and not self.is_internal: + self.path = self.url_to_local_path(self.parsed_url, base) + + def __hash__(self): + if self.path is None: + return hash(self.url) + return hash(self.path) + + def __eq__(self, other): + return self.path == getattr(other, 'path', other) + + def __str__(self): + return u'Link: %s --> %s'%(self.url, self.path) + + +class IgnoreFile(Exception): + + def __init__(self, msg, errno): + Exception.__init__(self, msg) + self.doesnt_exist = errno == 2 + self.errno = errno + +class HTMLFile(object): + ''' + Contains basic information about an HTML file. This + includes a list of links to other files as well as + the encoding of each file. Also tries to detect if the file is not a HTML + file in which case :member:`is_binary` is set to True. + + The encoding of the file is available as :member:`encoding`. + ''' + + HTML_PAT = re.compile(r'<\s*html', re.IGNORECASE) + TITLE_PAT = re.compile('([^<>]+)', re.IGNORECASE) + LINK_PAT = re.compile( + r'<\s*a\s+.*?href\s*=\s*(?:(?:"(?P[^"]+)")|(?:\'(?P[^\']+)\')|(?P[^\s]+))', + re.DOTALL|re.IGNORECASE) + + def __init__(self, path_to_html_file, level, encoding, verbose, referrer=None): + ''' + :param level: The level of this file. Should be 0 for the root file. + :param encoding: Use `encoding` to decode HTML. + :param referrer: The :class:`HTMLFile` that first refers to this file. + ''' + self.path = unicode_path(path_to_html_file, abs=True) + self.title = os.path.splitext(os.path.basename(self.path))[0] + self.base = os.path.dirname(self.path) + self.level = level + self.referrer = referrer + self.links = [] + + try: + with open(self.path, 'rb') as f: + src = f.read() + except IOError, err: + msg = 'Could not read from file: %s with error: %s'%(self.path, unicode(err)) + if level == 0: + raise IOError(msg) + raise IgnoreFile(msg, err.errno) + + self.is_binary = not bool(self.HTML_PAT.search(src[:1024])) + self.title = None + if not self.is_binary: + if encoding is None: + encoding = xml_to_unicode(src[:4096], verbose=verbose)[-1] + self.encoding = encoding + else: + self.encoding = encoding + + src = src.decode(encoding, 'replace') + match = self.TITLE_PAT.search(src) + self.title = match.group(1) if match is not None else None + self.find_links(src) + + + + def __eq__(self, other): + return self.path == getattr(other, 'path', other) + + def __str__(self): + return u'HTMLFile:%d:%s:%s'%(self.level, 'b' if self.is_binary else 'a', self.path) + + def __repr__(self): + return str(self) + + + def find_links(self, src): + for match in self.LINK_PAT.finditer(src): + url = None + for i in ('url1', 'url2', 'url3'): + url = match.group(i) + if url: + break + link = self.resolve(url) + if link not in self.links: + self.links.append(link) + + def resolve(self, url): + return Link(url, self.base) + + +def depth_first(root, flat, visited=set([])): + yield root + visited.add(root) + for link in root.links: + if link.path is not None and link not in visited: + try: + index = flat.index(link) + except ValueError: # Can happen if max_levels is used + continue + hf = flat[index] + if hf not in visited: + yield hf + visited.add(hf) + for hf in depth_first(hf, flat, visited): + if hf not in visited: + yield hf + visited.add(hf) + + +def traverse(path_to_html_file, max_levels=sys.maxint, verbose=0, encoding=None): + ''' + Recursively traverse all links in the HTML file. + + :param max_levels: Maximum levels of recursion. Must be non-negative. 0 + implies that no links in the root HTML file are followed. + :param encoding: Specify character encoding of HTML files. If `None` it is + auto-detected. + :return: A pair of lists (breadth_first, depth_first). Each list contains + :class:`HTMLFile` objects. + ''' + assert max_levels >= 0 + level = 0 + flat = [HTMLFile(path_to_html_file, level, encoding, verbose)] + next_level = list(flat) + while level < max_levels and len(next_level) > 0: + level += 1 + nl = [] + for hf in next_level: + rejects = [] + for link in hf.links: + if link.path is None or link.path in flat: + continue + try: + nf = HTMLFile(link.path, level, encoding, verbose, referrer=hf) + if nf.is_binary: + raise IgnoreFile('%s is a binary file'%nf.path, -1) + nl.append(nf) + flat.append(nf) + except IgnoreFile, err: + rejects.append(link) + if not err.doesnt_exist or verbose > 1: + print str(err) + for link in rejects: + hf.links.remove(link) + + next_level = list(nl) + return flat, list(depth_first(flat[0], flat)) + + +def opf_traverse(opf_reader, verbose=0, encoding=None): + ''' + Return a list of :class:`HTMLFile` objects in the order specified by the + `` element of the OPF. + + :param opf_reader: An :class:`calibre.ebooks.metadata.opf.OPFReader` instance. + :param encoding: Specify character encoding of HTML files. If `None` it is + auto-detected. + ''' + if not opf_reader.spine: + raise ValueError('OPF does not have a spine') + flat = [] + for path in opf_reader.spine.items(): + path = os.path.abspath(path) + if path not in flat: + flat.append(os.path.abspath(path)) + for item in opf_reader.manifest: + if 'html' in item.mime_type: + path = os.path.abspath(item.path) + if path not in flat: + flat.append(path) + for i, path in enumerate(flat): + if not os.path.exists(path): + path = path.replace('&', '%26') + if os.path.exists(path): + flat[i] = path + for item in opf_reader.itermanifest(): + item.set('href', item.get('href').replace('&', '%26')) + ans = [] + for path in flat: + if os.path.exists(path): + ans.append(HTMLFile(path, 0, encoding, verbose)) + else: + print 'WARNING: OPF spine item %s does not exist'%path + ans = [f for f in ans if not f.is_binary] + return ans + + + +class PreProcessor(object): + PREPROCESS = [(re.compile(r'&(\S+?);'), entity_to_unicode)] + + # Fix pdftohtml markup + PDFTOHTML = [ + # Remove


tags + (re.compile(r'', re.IGNORECASE), lambda match: ' '), + # Remove page numbers + (re.compile(r'\d+
', re.IGNORECASE), lambda match: ''), + # Remove
and replace

with

+ (re.compile(r'\s*', re.IGNORECASE), lambda match: '

'), + (re.compile(r'(.*)', re.IGNORECASE), + lambda match: match.group() if re.match('<', match.group(1).lstrip()) or len(match.group(1)) < 40 + else match.group(1)), + # Remove hyphenation + (re.compile(r'-\n\r?'), lambda match: ''), + + # Remove gray background + (re.compile(r']+>'), lambda match : '') + + ] + + # Fix Book Designer markup + BOOK_DESIGNER = [ + # HR + (re.compile('


', re.IGNORECASE), + lambda match : ' '), + # Create header tags + (re.compile('<]*?id=BookTitle[^><]*?(align=)*(?(1)(\w+))*[^><]*?>[^><]*?

', re.IGNORECASE), + lambda match : '

%s

'%(match.group(2) if match.group(2) else 'center', match.group(3))), + (re.compile('<]*?id=BookAuthor[^><]*?(align=)*(?(1)(\w+))*[^><]*?>[^><]*?', re.IGNORECASE), + lambda match : '

%s

'%(match.group(2) if match.group(2) else 'center', match.group(3))), + (re.compile('<]*?id=title[^><]*?>(.*?)', re.IGNORECASE|re.DOTALL), + lambda match : '

%s

'%(match.group(1),)), + (re.compile('<]*?id=subtitle[^><]*?>(.*?)', re.IGNORECASE|re.DOTALL), + lambda match : '

%s

'%(match.group(1),)), + ] + + def is_baen(self, src): + return re.compile(r'<]*id=BookTitle', raw) is not None + + def is_pdftohtml(self, src): + return '' in src[:1000] + + def preprocess(self, html): + opts = getattr(self, 'opts', False) + if opts and hasattr(opts, 'profile') and getattr(opts.profile, 'remove_soft_hyphens', False): + html = html.replace(u'\u00ad', '') + if self.is_baen(html): + rules = [] + elif self.is_book_designer(html): + rules = self.BOOK_DESIGNER + elif self.is_pdftohtml(html): + rules = self.PDFTOHTML + else: + rules = [] + for rule in self.PREPROCESS + rules: + html = rule[0].sub(rule[1], html) + + return html + +class Parser(PreProcessor, LoggingInterface): +# SELF_CLOSING_TAGS = 'hr|br|link|img|meta|input|area|base|basefont' +# SELF_CLOSING_RULES = [re.compile(p[0]%SELF_CLOSING_TAGS, re.IGNORECASE) for p in +# [ +# (r'<(?P%s)(?P(\s+[^<>]*){0,1})(?', +# '<\g\g />'), +# (), +# ] +# ] + + def __init__(self, htmlfile, opts, tdir, resource_map, htmlfiles, name='htmlparser'): + LoggingInterface.__init__(self, logging.getLogger(name)) + self.setup_cli_handler(opts.verbose) + self.htmlfile = htmlfile + self.opts = opts + self.tdir = tdir + self.resource_map = resource_map + self.htmlfiles = htmlfiles + self.resource_dir = os.path.join(tdir, 'resources') + save_counter = 1 + self.htmlfile_map = {} + self.level = self.htmlfile.level + for f in self.htmlfiles: + name = os.path.basename(f.path) + if name in self.htmlfile_map.values(): + name = os.path.splitext(name)[0] + '_cr_%d'%save_counter + os.path.splitext(name)[1] + save_counter += 1 + self.htmlfile_map[f.path] = name + + self.parse_html() + self.root.rewrite_links(self.rewrite_links, resolve_base_href=False) + for bad in ('xmlns', 'lang', 'xml:lang'): # lxml also adds these attributes for XHTML documents, leading to duplicates + if self.root.get(bad, None) is not None: + self.root.attrib.pop(bad) + + def save_path(self): + return os.path.join(self.tdir, self.htmlfile_map[self.htmlfile.path]) + + def save(self): + ''' + Save processed HTML into the content directory. + Should be called after all HTML processing is finished. + ''' + ans = tostring(self.root, pretty_print=self.opts.pretty_print) + ans = re.compile(r'', re.IGNORECASE).sub('', ans[:1000]) + ans[1000:] + ans = re.compile(r'', re.IGNORECASE).sub('\n\t\n', ans[:1000])+ans[1000:] + + with open(self.save_path(), 'wb') as f: + f.write(ans) + return f.name + + + def parse_html(self): + ''' Create lxml ElementTree from HTML ''' + self.log_info('\tParsing '+os.sep.join(self.htmlfile.path.split(os.sep)[-3:])) + src = open(self.htmlfile.path, 'rb').read().decode(self.htmlfile.encoding, 'replace').strip() + src = self.preprocess(src) + # lxml chokes on unicode input when it contains encoding declarations + for pat in ENCODING_PATS: + src = pat.sub('', src) + try: + self.root = fromstring(src) + except: + if self.opts.verbose: + self.log_exception('lxml based parsing failed') + self.root = soupparser.fromstring(src, makeelement=parser.makeelement) + head = self.root.xpath('./head') + if head: + head = head[0] + else: + head = etree.SubElement(self.root, 'head') + self.root.remove(head) + self.root.insert(0, head) + + self.head = head + self.body = self.root.body + for a in self.root.xpath('//a[@name]'): + a.set('id', a.get('name')) + if not self.head.xpath('./title'): + title = etree.SubElement(self.head, 'title') + title.text = _('Unknown') + + def debug_tree(self, name): + ''' + Dump source tree for later debugging. + ''' + tdir = tempfile.gettempdir() + if not os.path.exists(tdir): + os.makedirs(tdir) + with open(os.path.join(tdir, '%s-%s.html'%\ + (os.path.basename(self.htmlfile.path), name)), 'wb') as f: + f.write(tostring(self.root, encoding='utf-8')) + self.log_debug(_('Written processed HTML to ')+f.name) + + + def rewrite_links(self, olink): + ''' + Make all links in document relative so that they work in the EPUB container. + Also copies any resources (like images, stylesheets, scripts, etc.) into + the local tree. + ''' + if not isinstance(olink, unicode): + olink = olink.decode(self.htmlfile.encoding) + link = self.htmlfile.resolve(olink) + frag = (('#'+link.fragment) if link.fragment else '') + if link.path == self.htmlfile.path: + return frag if frag else '#' + if not link.path or not os.path.exists(link.path) or not os.path.isfile(link.path): + return olink + if link.path in self.htmlfiles: + return self.htmlfile_map[link.path] + frag + if re.match(r'\.(x){0,1}htm(l){0,1}', os.path.splitext(link.path)[1]) is not None: + return olink # This happens when --max-levels is used + if link.path in self.resource_map.keys(): + return self.resource_map[link.path] + frag + name = os.path.basename(link.path) + name, ext = os.path.splitext(name) + name += ('_%d'%len(self.resource_map)) + ext + shutil.copyfile(link.path, os.path.join(self.resource_dir, name)) + name = 'resources/' + name + self.resource_map[link.path] = name + return name + frag + + + +class Processor(Parser): + ''' + This class builds on :class:`Parser` to provide additional methods + to perform various processing/modification tasks on HTML files. + ''' + + LINKS_PATH = XPath('//a[@href]') + PIXEL_PAT = re.compile(r'([-]?\d+|[-]?\d*\.\d+)px') + + def __init__(self, *args, **kwargs): + Parser.__init__(self, *args, **kwargs) + temp = LoggingInterface(logging.getLogger('cssutils')) + temp.setup_cli_handler(self.opts.verbose) + self.css_parser = CSSParser(log=temp.logger, loglevel=logging.ERROR) + self.stylesheet = self.font_css = self.override_css = None + + def detect_chapters(self): + self.detected_chapters = self.opts.chapter(self.root) + for elem in self.detected_chapters: + text = u' '.join([t.strip() for t in elem.xpath('descendant::text()')]) + self.log_info('\tDetected chapter: %s', text[:50]) + if self.opts.chapter_mark != 'none': + hr = etree.Element('hr') + if elem.getprevious() is None: + elem.getparent()[:0] = [hr] + else: + insert = None + for i, c in enumerate(elem.getparent()): + if c is elem: + insert = i + break + elem.getparent()[insert:insert] = [hr] + if self.opts.chapter_mark != 'rule': + hr.set('style', 'width:0pt;page-break-before:always') + if self.opts.chapter_mark == 'both': + hr2 = etree.Element('hr') + hr2.tail = u'\u00a0' + p = hr.getparent() + i = p.index(hr) + p[i:i] = [hr2] + + + + def save(self): + style_path = os.path.splitext(os.path.basename(self.save_path()))[0] + for i, sheet in enumerate([self.stylesheet, self.font_css, self.override_css]): + if sheet is not None: + style = etree.SubElement(self.head, 'link', attrib={'type':'text/css', 'rel':'stylesheet', + 'href':'resources/%s_%d.css'%(style_path, i), + 'charset':'UTF-8'}) + style.tail = '\n' + path = os.path.join(os.path.dirname(self.save_path()), *(style.get('href').split('/'))) + self.resource_map[path] = style.get('href') + open(path, 'wb').write(getattr(sheet, 'cssText', sheet).encode('utf-8')) + return Parser.save(self) + + def populate_toc(self, toc): + ''' + 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) + + name = self.htmlfile_map[self.htmlfile.path] + href = 'content/'+name + + # Add level 1 and level 2 TOC items + counter = 0 + if self.opts.level1_toc is not None: + level1 = self.opts.level1_toc(self.root) + if level1: + added = {} + for elem in level1: + text = (u''.join(elem.xpath('string()'))).strip() + if text: + id = elem.get('id', 'calibre_chapter_%d'%counter) + counter += 1 + elem.set('id', id) + added[elem] = add_item(href, id, text, toc, type='chapter') + add_item(href, id, 'Top', added[elem], type='chapter') + if self.opts.level2_toc is not None: + level2 = list(self.opts.level2_toc(self.root)) + for elem in level2: + level1 = None + for item in self.root.iterdescendants(): + if item in added.keys(): + level1 = added[item] + elif item == elem and level1 is not None: + text = (u''.join(elem.xpath('string()'))).strip() + if text: + id = elem.get('id', 'calibre_chapter_%d'%counter) + counter += 1 + elem.set('id', id) + add_item(href, id, text, level1, type='chapter') + + + # Add chapters to TOC + + if not self.opts.no_chapters_in_toc: + for elem in getattr(self, 'detected_chapters', []): + text = (u''.join(elem.xpath('string()'))).strip() + if text: + counter += 1 + id = elem.get('id', 'calibre_chapter_%d'%counter) + elem.set('id', id) + add_item(href, id, text, toc, type='chapter') + + + referrer = toc + if self.htmlfile.referrer is not None: + try: + name = self.htmlfile_map[self.htmlfile.referrer] + href = 'content/'+name + for i in toc.flat(): + if href == i.href and i.fragment is None: + referrer = i + break + except KeyError: + pass + + + + + + if referrer.href != href: # Happens for root file + target = add_item(href, None, unicode(self.htmlfile.title), referrer, type='file') + + # Add links to TOC + if int(self.opts.max_toc_links) > 0: + for link in list(self.LINKS_PATH(self.root))[:self.opts.max_toc_links]: + text = (u''.join(link.xpath('string()'))).strip() + if text: + href = link.get('href', '') + if href: + href = 'content/'+href + parts = href.split('#') + href, fragment = parts[0], None + if len(parts) > 1: + fragment = parts[1] + if self.htmlfile.referrer is not None: + name = self.htmlfile_map[self.htmlfile.referrer.path] + add_item(href, fragment, text, target) + + @classmethod + def preprocess_css(cls, css, dpi=96): + def rescale(match): + val = match.group(1) + try: + val = float(val) + except ValueError: + return '' + return '%fpt'%(72 * val/dpi) + + return cls.PIXEL_PAT.sub(rescale, css) + + def extract_css(self, parsed_sheets): + ''' + Remove all CSS information from the document and store it as + :class:`StyleSheet` objects. + ''' + + def get_id(chapter, counter, prefix='calibre_css_'): + new_id = '%s_%d'%(prefix, counter) + if chapter.tag.lower() == 'a' and 'name' in chapter.keys(): + chapter.attrib['id'] = id = chapter.get('name') + if not id: + chapter.attrib['id'] = chapter.attrib['name'] = new_id + return new_id + if 'id' in chapter.keys(): + id = chapter.get('id') + else: + id = new_id + chapter.set('id', id) + return id + + self.external_stylesheets, self.stylesheet = [], self.css_parser.parseString('') + for link in self.root.xpath('//link'): + if 'css' in link.get('type', 'text/css').lower(): + file = os.path.join(self.tdir, *(link.get('href', '').split('/'))) + if file and not 'http:' in file: + if not parsed_sheets.has_key(file): + try: + self.log_info('Processing stylesheet %s...'%file) + css = self.preprocess_css(open(file).read()) + except (IOError, OSError): + self.log_error('Failed to open stylesheet: %s'%file) + else: + try: + parsed_sheets[file] = self.css_parser.parseString(css) + except: + parsed_sheets[file] = css.decode('utf8', 'replace') + self.log_warning('Failed to parse stylesheet: %s'%file) + if self.opts.verbose > 1: + self.log_exception('') + if parsed_sheets.has_key(file): + self.external_stylesheets.append(parsed_sheets[file]) + + + for style in self.root.xpath('//style'): + if 'css' in style.get('type', 'text/css').lower(): + raw = '\n'.join(style.xpath('./text()')) + css = self.preprocess_css(raw) + try: + sheet = self.css_parser.parseString(css) + except: + self.log_debug('Failed to parse style element') + else: + for rule in sheet: + self.stylesheet.add(rule) + style.getparent().remove(style) + cache = {} + class_counter = 0 + for font in self.root.xpath('//font'): + try: + size = int(font.attrib.pop('size', '3')) + except: + size = 3 + setting = 'font-size: %d%%;'%int((float(size)/3) * 100) + face = font.attrib.pop('face', None) + if face is not None: + setting += 'font-face:%s;'%face + color = font.attrib.pop('color', None) + if color is not None: + setting += 'color:%s'%color + classname = cache.get(setting, None) + if classname is None: + classname = 'calibre_class_%d'%class_counter + class_counter += 1 + cache[setting] = classname + cn = font.get('class', '') + if cn: cn += ' ' + cn += classname + font.set('class', cn) + font.tag = 'span' + + for elem in self.root.xpath('//*[@style]'): + setting = elem.get('style') + classname = cache.get(setting, None) + if classname is None: + classname = 'calibre_class_%d'%class_counter + class_counter += 1 + cache[setting] = classname + cn = elem.get('class', '') + if cn: cn += ' ' + cn += classname + elem.set('class', cn) + elem.attrib.pop('style') + + css = '\n'.join(['.%s {%s;}'%(cn, setting) for \ + setting, cn in cache.items()]) + sheet = self.css_parser.parseString(self.preprocess_css(css)) + for rule in sheet: + self.stylesheet.add(rule) + css = '' + if self.opts.override_css: + css += '\n\n' + self.opts.override_css + css += '\n\n' + 'body {margin-top: 0pt; margin-bottom: 0pt; margin-left: 0pt; margin-right: 0pt;}' + css += '\n\n@page {margin-top: %fpt; margin-bottom: %fpt; margin-left: %fpt; margin-right: %fpt}'%(self.opts.margin_top, self.opts.margin_bottom, self.opts.margin_left, self.opts.margin_right) + if self.opts.remove_paragraph_spacing: + css += '\n\np {text-indent: 2.1em; margin-top:1pt; margin-bottom:1pt; padding:0pt; border:0pt;}' + self.override_css = self.css_parser.parseString(self.preprocess_css(css)) + + +def config(defaults=None, config_name='html', + desc=_('Options to control the traversal of HTML')): + if defaults is None: + c = Config(config_name, desc) + else: + c = StringConfig(defaults, desc) + + c.add_opt('output', ['-o', '--output'], default=None, + help=_('The output directory. Default is the current directory.')) + c.add_opt('encoding', ['--encoding'], default=None, + help=_('Character encoding for HTML files. Default is to auto detect.')) + c.add_opt('zip', ['--zip'], default=False, + help=_('Create the output in a zip file. If this option is specified, the --output should be the name of a file not a directory.')) + + traversal = c.add_group('traversal', _('Control the following of links in HTML files.')) + traversal('breadth_first', ['--breadth-first'], default=False, + help=_('Traverse links in HTML files breadth first. Normally, they are traversed depth first')) + traversal('max_levels', ['--max-levels'], default=sys.getrecursionlimit(), group='traversal', + help=_('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.')) + + metadata = c.add_group('metadata', _('Set metadata of the generated ebook')) + metadata('title', ['-t', '--title'], default=None, + help=_('Set the title. Default is to autodetect.')) + metadata('authors', ['-a', '--authors'], default=None, + help=_('The author(s) of the ebook, as a comma separated list.')) + metadata('tags', ['--subjects'], default=None, + help=_('The subject(s) of this book, as a comma separated list.')) + metadata('publisher', ['--publisher'], default=None, + help=_('Set the publisher of this book.')) + metadata('comments', ['--comment'], default=None, + help=_('A summary of this book.')) + metadata('from_opf', ['--metadata-from'], default=None, + help=_('Load metadata from the specified OPF file')) + + debug = c.add_group('debug', _('Options useful for debugging')) + debug('verbose', ['-v', '--verbose'], default=0, action='count', + help=_('Be more verbose while processing. Can be specified multiple times to increase verbosity.')) + debug('pretty_print', ['--pretty-print'], default=False, + help=_('Output HTML is "pretty printed" for easier parsing by humans')) + + return c + +def option_parser(): + c = config() + return c.option_parser(usage=_('''\ +%prog [options] file.html|opf + +Follow all links in an HTML file and collect them into the specified directory. +Also collects any references resources like images, stylesheets, scripts, etc. +If an OPF file is specified instead, the list of files in its element +is used. +''')) + +def search_for_opf(dir): + for f in os.listdir(dir): + if f.lower().endswith('.opf'): + return OPF(open(os.path.join(dir, f), 'rb'), dir) + + +def get_filelist(htmlfile, opts): + ''' + Build list of files referenced by html file or try to detect and use an + OPF file instead. + ''' + print 'Building file list...' + dir = os.path.dirname(htmlfile) + if not dir: + dir = os.getcwd() + opf = search_for_opf(dir) + filelist = None + if opf is not None: + try: + filelist = opf_traverse(opf, verbose=opts.verbose, encoding=opts.encoding) + except: + pass + if not filelist: + filelist = traverse(htmlfile, max_levels=int(opts.max_levels), + verbose=opts.verbose, encoding=opts.encoding)\ + [0 if opts.breadth_first else 1] + if opts.verbose: + print '\tFound files...' + for f in filelist: + print '\t\t', f + return opf, filelist + +def parse_content(filelist, opts): + ''' + Parse content, rewriting links and copying resources. + ''' + if not opts.output: + opts.output = '.' + opts.output = os.path.abspath(opts.output) + rdir = os.path.join(opts.output, 'content', 'resources') + if not os.path.exists(rdir): + os.makedirs(rdir) + resource_map = {} + for htmlfile in filelist: + p = Parser(htmlfile, opts, os.path.join(opts.output, 'content'), + resource_map, filelist) + p.save() + return resource_map, p.htmlfile_map + +def merge_metadata(htmlfile, opf, opts): + ''' + Merge metadata from various sources. + ''' + if opf: + mi = MetaInformation(opf) + else: + try: + 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'): + val = getattr(opts, attr, None) + if val is None or val == _('Unknown') or val == [_('Unknown')]: + continue + if attr in ('authors', 'tags'): + val = [i.strip() for i in val.split(',') if i.strip()] + setattr(mi, attr, val) + if not mi.title: + mi.title = os.path.splitext(os.path.basename(htmlfile))[0] + if not mi.authors: + mi.authors = [_('Unknown')] + return mi + +def create_metadata(basepath, mi, filelist, resources): + ''' + Create an OPF metadata object with correct spine and manifest. + ''' + mi = OPFCreator(basepath, mi) + mi.guide = None + entries = [('content/'+f, 'application/xhtml+xml') for f in filelist] + [(f, None) for f in resources] + for f in filelist: + if os.path.exists(os.path.join(basepath, 'content', 'resources', f+'.css')): + entries.append(('content/resources/'+f+'.css', 'text/css')) + mi.create_manifest(entries) + mi.create_spine(['content/'+f for f in filelist]) + return mi + +def rebase_toc(toc, htmlfile_map, basepath, root=True): + ''' + Rebase a :class:`calibre.ebooks.metadata.toc.TOC` object. Maps all entries + in the TOC to point to their new locations relative to the new OPF file. + ''' + def fix_entry(entry): + if entry.abspath in htmlfile_map.keys(): + entry.href = 'content/' + htmlfile_map[entry.abspath] + + for entry in toc: + rebase_toc(entry, htmlfile_map, basepath, root=False) + fix_entry(entry) + if root: + toc.base_path = basepath + +def create_dir(htmlfile, opts): + ''' + Create a directory that contains the open ebook + ''' + if htmlfile.lower().endswith('.opf'): + opf = OPF(open(htmlfile, 'rb'), os.path.dirname(os.path.abspath(htmlfile))) + filelist = opf_traverse(opf, verbose=opts.verbose, encoding=opts.encoding) + mi = MetaInformation(opf) + else: + opf, filelist = get_filelist(htmlfile, opts) + mi = merge_metadata(htmlfile, opf, opts) + + resource_map, htmlfile_map = parse_content(filelist, opts) + resources = [os.path.join(opts.output, 'content', f) for f in resource_map.values()] + + if opf and opf.cover and os.access(opf.cover, os.R_OK): + cpath = os.path.join(opts.output, 'content', 'resources', '_cover_'+os.path.splitext(opf.cover)[-1]) + shutil.copyfile(opf.cover, cpath) + resources.append(cpath) + mi.cover = cpath + + spine = [htmlfile_map[f.path] for f in filelist] + mi = create_metadata(opts.output, mi, spine, resources) + buf = cStringIO.StringIO() + if mi.toc: + rebase_toc(mi.toc, htmlfile_map, opts.output) + with open(os.path.join(opts.output, 'metadata.opf'), 'wb') as f: + mi.render(f, buf) + toc = buf.getvalue() + if toc: + with open(os.path.join(opts.output, 'toc.ncx'), 'wb') as f: + f.write(toc) + print 'Open ebook created in', opts.output + +def create_oebzip(htmlfile, opts): + ''' + Create a zip file that contains the Open ebook. + ''' + tdir = PersistentTemporaryDirectory('_create_oebzip') + if opts.output is None: + opts.output = os.path.join(os.path.splitext(htmlfile)[0]+'.oeb.zip') + ofile = opts.output + opts.output = tdir + create_dir(htmlfile, opts) + zf = ZipFile(ofile, 'w') + zf.add_dir(opts.output) + print 'Output saved to', ofile + +def main(args=sys.argv): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) < 2: + parser.print_help() + print _('You must specify an input HTML file') + return 1 + + htmlfile = args[1] + if opts.zip: + create_oebzip(htmlfile, opts) + else: + create_dir(htmlfile, opts) + + return 0 + +def gui_main(htmlfile): + ''' + Convenience wrapper for use in recursively importing HTML files. + ''' + pt = PersistentTemporaryFile('_html2oeb_gui.oeb.zip') + pt.close() + opts = ''' +pretty_print = True +max_levels = 5 +output = %s +'''%repr(pt.name) + c = config(defaults=opts) + opts = c.parse() + create_oebzip(htmlfile, opts) + zf = ZipFile(pt.name, 'r') + nontrivial = [f for f in zf.infolist() if f.compress_size > 1 and not f.filename.endswith('.opf')] + if len(nontrivial) < 2: + return None + return pt.name + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 87d0a29088..1a08803126 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -14,6 +14,7 @@ from lxml import etree from calibre.ebooks.lit import LitError from calibre.ebooks.lit.maps import OPF_MAP, HTML_MAP import calibre.ebooks.lit.mssha1 as mssha1 +from calibre.ebooks import DRMError from calibre import plugins lzx, lxzerror = plugins['lzx'] msdes, msdeserror = plugins['msdes'] @@ -543,7 +544,10 @@ class LitReader(object): raise LitError('Directory entry had 64bit name length.') if namelen > remaining - 3: raise LitError('Read past end of directory chunk') - name, chunk = chunk[:namelen].decode('utf-8'), chunk[namelen:] + try: + name, chunk = chunk[:namelen].decode('utf-8'), chunk[namelen:] + except UnicodeDecodeError: + break section, chunk, remaining = encint(chunk, remaining) offset, chunk, remaining = encint(chunk, remaining) size, chunk, remaining = encint(chunk, remaining) @@ -650,7 +654,7 @@ class LitReader(object): raise LitError('Unable to decrypt title key!') self.bookkey = bookkey[1:9] else: - raise LitError('Cannot extract content from a DRM protected ebook') + raise DRMError() def _calculate_deskey(self): hashfiles = ['/meta', '/DRMStorage/DRMSource'] diff --git a/src/calibre/ebooks/lrf/__init__.py b/src/calibre/ebooks/lrf/__init__.py index 03d59d825d..3515c75c7d 100644 --- a/src/calibre/ebooks/lrf/__init__.py +++ b/src/calibre/ebooks/lrf/__init__.py @@ -22,6 +22,8 @@ __docformat__ = "epytext" preferred_source_formats = [ 'LIT', 'MOBI', + 'EPUB', + 'ODT', 'HTML', 'HTM', 'XHTM', @@ -163,7 +165,7 @@ def option_parser(usage, gui_mode=False): help=_('''The regular expression used to detect chapter titles.''' ''' It is searched for in heading tags (h1-h6). Defaults to %default''')) chapter.add_option('--chapter-attr', default='$,,$', - help=_('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". Default is %default''')) + help=_('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

tags, you would use "h2,none,". Default is %default''')) chapter.add_option('--page-break-before-tag', dest='page_break', default='h[12]', help=_('''If html2lrf does not find any page breaks in the ''' '''html file and cannot detect chapter headings, it will ''' diff --git a/src/calibre/ebooks/lrf/any/convert_from.py b/src/calibre/ebooks/lrf/any/convert_from.py index 246473c2b2..710fbe1690 100644 --- a/src/calibre/ebooks/lrf/any/convert_from.py +++ b/src/calibre/ebooks/lrf/any/convert_from.py @@ -1,12 +1,14 @@ +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''Convert any ebook file into a LRF file.''' -import sys, os, logging, shutil, tempfile, glob, re +import sys, os, logging, shutil, tempfile, re from calibre.ebooks import UnknownFormatError from calibre.ebooks.lrf import option_parser as _option_parser from calibre import __appname__, setup_cli_handlers, extract +from calibre.ptempfile import TemporaryDirectory from calibre.ebooks.lrf.lit.convert_from import process_file as lit2lrf from calibre.ebooks.lrf.pdf.convert_from import process_file as pdf2lrf from calibre.ebooks.lrf.rtf.convert_from import process_file as rtf2lrf @@ -28,12 +30,18 @@ def largest_file(files): def find_htmlfile(dir): ext_pat = re.compile(r'\.(x){0,1}htm(l){0,1}', re.IGNORECASE) toc_pat = re.compile(r'toc', re.IGNORECASE) - toc_files, files = [], [] - for f in map(lambda x:os.path.join(dir, x), os.listdir(dir)): - name, ext = os.path.splitext(f) - if ext and ext_pat.match(ext): - toc_files.append(f) if toc_pat.search(f) else files.append(f) - a = toc_files if toc_files else files + index_pat = re.compile(r'index', re.IGNORECASE) + toc_files, index_files, files = [], [], [] + + for root, dirs, _files in os.walk(dir): + for f in _files: + f = os.path.abspath(os.path.join(root, f)) + ext = os.path.splitext(f)[1] + if ext and ext_pat.match(ext): + toc_files.append(f) if toc_pat.search(f) else \ + index_files.append(f) if index_pat.search(f) else \ + files.append(f) + a = toc_files if toc_files else index_files if index_files else files if a: return largest_file(a) @@ -74,7 +82,7 @@ def handle_archive(path): candidates = map(lambda x:os.path.join(cdir, x), os.listdir(cdir)) for ext in exts: for f in candidates: - if f.lower().endswith(ext): + if f.lower().endswith('.'+ext): files.append(f) file = largest_file(files) if not file: @@ -83,6 +91,21 @@ def handle_archive(path): file = file.decode(sys.getfilesystemencoding()) return tdir, file +def odt2lrf(path, options, logger): + from calibre.ebooks.odt.to_oeb import Extract + from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file + + if logger is None: + level = logging.DEBUG if options.verbose else logging.INFO + logger = logging.getLogger('odt2lrf') + setup_cli_handlers(logger, level) + + with TemporaryDirectory('_odt2lrf') as tdir: + opf = Extract()(path, tdir) + options.use_spine = True + options.encoding = 'utf-8' + html_process_file(opf.replace('metadata.opf', 'index.html'), options, logger) + def process_file(path, options, logger=None): path = os.path.abspath(os.path.expanduser(path)) tdir = None @@ -103,7 +126,7 @@ def process_file(path, options, logger=None): fmt = '.lrs' if options.lrs else '.lrf' options.output = os.path.splitext(os.path.basename(path))[0] + fmt options.output = os.path.abspath(os.path.expanduser(options.output)) - if ext in ['zip', 'rar']: + if ext in ['zip', 'rar', 'oebzip']: newpath = None try: tdir, newpath = handle_archive(path) @@ -132,8 +155,10 @@ def process_file(path, options, logger=None): convertor = mobi2lrf elif ext == 'fb2': convertor = fb22lrf + elif ext == 'odt': + convertor = odt2lrf if not convertor: - raise UnknownFormatError('Coverting from %s to LRF is not supported.'%ext) + raise UnknownFormatError(_('Converting from %s to LRF is not supported.')%ext) convertor(path, options, logger) finally: os.chdir(cwd) diff --git a/src/calibre/ebooks/lrf/comic/convert_from.py b/src/calibre/ebooks/lrf/comic/convert_from.py index 33d697bfe4..a3597bfaa8 100755 --- a/src/calibre/ebooks/lrf/comic/convert_from.py +++ b/src/calibre/ebooks/lrf/comic/convert_from.py @@ -7,16 +7,18 @@ __docformat__ = 'restructuredtext en' Based on ideas from comiclrf created by FangornUK. ''' -import os, sys, traceback, shutil +import os, sys, shutil, traceback, textwrap from uuid import uuid4 -from calibre import extract, detect_ncpus, terminal_controller, \ - __appname__, __version__ +from calibre import extract, terminal_controller, __appname__, __version__ from calibre.utils.config import Config, StringConfig from calibre.ptempfile import PersistentTemporaryDirectory -from calibre.utils.threadpool import ThreadPool, WorkRequest +from calibre.parallel import Server, ParallelJob from calibre.utils.terminfo import ProgressBar from calibre.ebooks.lrf.pylrs.pylrs import Book, BookSetting, ImageStream, ImageBlock +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.epub.from_html import config as html2epub_config, convert as html2epub try: from calibre.utils.PythonMagickWand import \ NewMagickWand, NewPixelWand, \ @@ -27,7 +29,7 @@ try: MagickGetImageHeight, \ MagickResizeImage, MagickSetImageType, \ GrayscaleType, CatromFilter, MagickSetImagePage, \ - MagickBorderImage, MagickSharpenImage, \ + MagickBorderImage, MagickSharpenImage, MagickDespeckleImage, \ MagickQuantizeImage, RGBColorspace, \ MagickWriteImage, DestroyPixelWand, \ DestroyMagickWand, CloneMagickWand, \ @@ -38,14 +40,14 @@ except: PROFILES = { # Name : (width, height) in pixels - 'prs500':(584, 754), + 'prs500':(584, 754), } def extract_comic(path_to_comic_file): ''' Un-archive the comic file. ''' - tdir = PersistentTemporaryDirectory(suffix='comic_extract') + tdir = PersistentTemporaryDirectory(suffix='_comic_extract') extract(path_to_comic_file, tdir) return tdir @@ -79,151 +81,200 @@ def find_pages(dir, sort_on_mtime=False, verbose=False): class PageProcessor(list): ''' - Contains the actual image rendering logic. See :method:`__call__` and + Contains the actual image rendering logic. See :method:`render` and :method:`process_pages`. ''' def __init__(self, path_to_page, dest, opts, num): - self.path_to_page = path_to_page - self.opts = opts - self.num = num - self.dest = dest - self.rotate = False list.__init__(self) + self.path_to_page = path_to_page + self.opts = opts + self.num = num + self.dest = dest + self.rotate = False + self.render() - def __call__(self): - try: - img = NewMagickWand() - if img < 0: + + def render(self): + img = NewMagickWand() + if img < 0: + raise RuntimeError('Cannot create wand.') + if not MagickReadImage(img, self.path_to_page): + raise IOError('Failed to read image from: %'%self.path_to_page) + width = MagickGetImageWidth(img) + height = MagickGetImageHeight(img) + if self.num == 0: # First image so create a thumbnail from it + thumb = CloneMagickWand(img) + if thumb < 0: raise RuntimeError('Cannot create wand.') - if not MagickReadImage(img, self.path_to_page): - raise IOError('Failed to read image from: %'%self.path_to_page) - width = MagickGetImageWidth(img) - height = MagickGetImageHeight(img) - - if self.num == 0: # First image so create a thumbnail from it - thumb = CloneMagickWand(img) - if thumb < 0: + MagickThumbnailImage(thumb, 60, 80) + MagickWriteImage(thumb, os.path.join(self.dest, 'thumbnail.png')) + DestroyMagickWand(thumb) + self.pages = [img] + if width > height: + if self.opts.landscape: + self.rotate = True + else: + split1, split2 = map(CloneMagickWand, (img, img)) + DestroyMagickWand(img) + if split1 < 0 or split2 < 0: raise RuntimeError('Cannot create wand.') - MagickThumbnailImage(thumb, 60, 80) - MagickWriteImage(thumb, os.path.join(self.dest, 'thumbnail.png')) - DestroyMagickWand(thumb) - - self.pages = [img] - - if width > height: - if self.opts.landscape: - self.rotate = True - else: - split1, split2 = map(CloneMagickWand, (img, img)) - if split1 < 0 or split2 < 0: - raise RuntimeError('Cannot create wand.') - DestroyMagickWand(img) - MagickCropImage(split1, (width/2)-1, height, 0, 0) - MagickCropImage(split2, (width/2)-1, height, width/2, 0 ) - self.pages = [split2, split1] if self.opts.right2left else [split1, split2] - - self.process_pages() - except Exception, err: - print 'Failed to process page: %s'%os.path.basename(self.path_to_page) - print 'Error:', err - if self.opts.verbose: - traceback.print_exc() + MagickCropImage(split1, (width/2)-1, height, 0, 0) + MagickCropImage(split2, (width/2)-1, height, width/2, 0 ) + self.pages = [split2, split1] if self.opts.right2left else [split1, split2] + self.process_pages() def process_pages(self): for i, wand in enumerate(self.pages): pw = NewPixelWand() - if pw < 0: - raise RuntimeError('Cannot create wand.') - PixelSetColor(pw, 'white') - - MagickSetImageBorderColor(wand, pw) - - if self.rotate: - MagickRotateImage(wand, pw, -90) + try: + if pw < 0: + raise RuntimeError('Cannot create wand.') + PixelSetColor(pw, 'white') - # 25 percent fuzzy trim? - MagickTrimImage(wand, 25*65535/100) - MagickSetImagePage(wand, 0,0,0,0) #Clear page after trim, like a "+repage" - - # Do the Photoshop "Auto Levels" equivalent - if not self.opts.dont_normalize: - MagickNormalizeImage(wand) - - sizex = MagickGetImageWidth(wand) - sizey = MagickGetImageHeight(wand) - - SCRWIDTH, SCRHEIGHT = PROFILES[self.opts.profile] - - if self.opts.keep_aspect_ratio: - # Preserve the aspect ratio by adding border - aspect = float(sizex) / float(sizey) - if aspect <= (float(SCRWIDTH) / float(SCRHEIGHT)): - newsizey = SCRHEIGHT - newsizex = int(newsizey * aspect) - deltax = (SCRWIDTH - newsizex) / 2 - deltay = 0 - else: - newsizex = SCRWIDTH - newsizey = int(newsizex / aspect) - deltax = 0 - deltay = (SCRHEIGHT - newsizey) / 2 - - MagickResizeImage(wand, newsizex, newsizey, CatromFilter, 1.0) MagickSetImageBorderColor(wand, pw) - MagickBorderImage(wand, pw, deltax, deltay) - else: - MagickResizeImage(wand, SCRWIDTH, SCRHEIGHT, CatromFilter, 1.0) + if self.rotate: + MagickRotateImage(wand, pw, -90) + + # 25 percent fuzzy trim? + MagickTrimImage(wand, 25*65535/100) + MagickSetImagePage(wand, 0,0,0,0) #Clear page after trim, like a "+repage" + # Do the Photoshop "Auto Levels" equivalent + if not self.opts.dont_normalize: + MagickNormalizeImage(wand) + sizex = MagickGetImageWidth(wand) + sizey = MagickGetImageHeight(wand) - if not self.opts.dont_sharpen: - MagickSharpenImage(wand, 0.0, 1.0) + SCRWIDTH, SCRHEIGHT = PROFILES[self.opts.profile] - MagickSetImageType(wand, GrayscaleType) - MagickQuantizeImage(wand, self.opts.colors, RGBColorspace, 0, 1, 0) - dest = '%d_%d.png'%(self.num, i) - dest = os.path.join(self.dest, dest) - MagickWriteImage(wand, dest+'8') - os.rename(dest+'8', dest) - self.append(dest) - - DestroyPixelWand(pw) - wand = DestroyMagickWand(wand) + if self.opts.keep_aspect_ratio: + # Preserve the aspect ratio by adding border + aspect = float(sizex) / float(sizey) + if aspect <= (float(SCRWIDTH) / float(SCRHEIGHT)): + newsizey = SCRHEIGHT + newsizex = int(newsizey * aspect) + deltax = (SCRWIDTH - newsizex) / 2 + deltay = 0 + else: + newsizex = SCRWIDTH + newsizey = int(newsizex / aspect) + deltax = 0 + deltay = (SCRHEIGHT - newsizey) / 2 + MagickResizeImage(wand, newsizex, newsizey, CatromFilter, 1.0) + MagickSetImageBorderColor(wand, pw) + MagickBorderImage(wand, pw, deltax, deltay) + elif self.opts.wide: + # Keep aspect and Use device height as scaled image width so landscape mode is clean + aspect = float(sizex) / float(sizey) + screen_aspect = float(SCRWIDTH) / float(SCRHEIGHT) + # Get dimensions of the landscape mode screen + # Add 25px back to height for the battery bar. + wscreenx = SCRHEIGHT + 25 + wscreeny = int(wscreenx / screen_aspect) + if aspect <= screen_aspect: + newsizey = wscreeny + newsizex = int(newsizey * aspect) + deltax = (wscreenx - newsizex) / 2 + deltay = 0 + else: + newsizex = wscreenx + newsizey = int(newsizex / aspect) + deltax = 0 + deltay = (wscreeny - newsizey) / 2 + MagickResizeImage(wand, newsizex, newsizey, CatromFilter, 1.0) + MagickSetImageBorderColor(wand, pw) + MagickBorderImage(wand, pw, deltax, deltay) + else: + MagickResizeImage(wand, SCRWIDTH, SCRHEIGHT, CatromFilter, 1.0) + + if not self.opts.dont_sharpen: + MagickSharpenImage(wand, 0.0, 1.0) + + MagickSetImageType(wand, GrayscaleType) + + if self.opts.despeckle: + MagickDespeckleImage(wand) + + MagickQuantizeImage(wand, self.opts.colors, RGBColorspace, 0, 1, 0) + dest = '%d_%d.png'%(self.num, i) + dest = os.path.join(self.dest, dest) + MagickWriteImage(wand, dest+'8') + os.rename(dest+'8', dest) + self.append(dest) + finally: + if pw > 0: + DestroyPixelWand(pw) + DestroyMagickWand(wand) -class Progress(object): +def render_pages(tasks, dest, opts, notification=None): + ''' + Entry point for the job server. + ''' + failures, pages = [], [] + with ImageMagick(): + for num, path in tasks: + try: + pages.extend(PageProcessor(path, dest, opts, num)) + msg = _('Rendered %s') + except: + failures.append(path) + msg = _('Failed %s') + if opts.verbose: + msg += '\n' + traceback.format_exc() + msg = msg%path + if notification is not None: + notification(0.5, msg) + + return pages, failures + + +class JobManager(object): + ''' + Simple job manager responsible for keeping track of overall progress. + ''' def __init__(self, total, update): self.total = total self.update = update self.done = 0 + self.add_job = lambda j: j + self.output = lambda j: j + self.start_work = lambda j: j + self.job_done = lambda j: j - def __call__(self, req, res): + def status_update(self, job): self.done += 1 - self.update(float(self.done)/self.total, - _('Rendered %s')%os.path.basename(req.callable.path_to_page)) - + #msg = msg%os.path.basename(job.args[0]) + self.update(float(self.done)/self.total, job.msg) + def process_pages(pages, opts, update): ''' Render all identified comic pages. ''' if not _imagemagick_loaded: raise RuntimeError('Failed to load ImageMagick') - with ImageMagick(): - tdir = PersistentTemporaryDirectory('_comic2lrf_pp') - processed_pages = [PageProcessor(path, tdir, opts, i) for i, path in enumerate(pages)] - tp = ThreadPool(detect_ncpus()) - update(0, '') - notify = Progress(len(pages), update) - for pp in processed_pages: - tp.putRequest(WorkRequest(pp, callback=notify)) - tp.wait() - ans, failures = [], [] + + tdir = PersistentTemporaryDirectory('_comic2lrf_pp') + job_manager = JobManager(len(pages), update) + server = Server() + jobs = [] + tasks = server.split(pages) + for task in tasks: + jobs.append(ParallelJob('render_pages', lambda s:s, job_manager=job_manager, + args=[task, tdir, opts])) + server.add_job(jobs[-1]) + server.wait() + server.killall() + server.close() + ans, failures = [], [] - for pp in processed_pages: - if len(pp) == 0: - failures.append(os.path.basename(pp.path_to_page)) - else: - ans += pp - return ans, failures, tdir + for job in jobs: + if job.result is None: + raise Exception(_('Failed to process comic: %s\n\n%s')%(job.exception, job.traceback)) + pages, failures_ = job.result + ans += pages + failures += failures_ + return ans, failures, tdir def config(defaults=None): desc = _('Options to control the conversion of comics (CBR, CBZ) files into ebooks') @@ -231,32 +282,36 @@ def config(defaults=None): c = Config('comic', desc) else: c = StringConfig(defaults, desc) - c.add_opt('title', ['-t', '--title'], + c.add_opt('title', ['-t', '--title'], help=_('Title for generated ebook. Default is to use the filename.')) - c.add_opt('author', ['-a', '--author'], - help=_('Set the author in the metadata of the generated ebook. Default is %default'), + c.add_opt('author', ['-a', '--author'], + help=_('Set the author in the metadata of the generated ebook. Default is %default'), default=_('Unknown')) - c.add_opt('output', ['-o', '--output'], - help=_('Path to output LRF file. By default a file is created in the current directory.')) + c.add_opt('output', ['-o', '--output'], + help=_('Path to output file. By default a file is created in the current directory.')) c.add_opt('colors', ['-c', '--colors'], type='int', default=64, help=_('Number of colors for grayscale image conversion. Default: %default')) - c.add_opt('dont_normalize', ['-n', '--disable-normalize'], default=False, + c.add_opt('dont_normalize', ['-n', '--disable-normalize'], default=False, help=_('Disable normalize (improve contrast) color range for pictures. Default: False')) c.add_opt('keep_aspect_ratio', ['-r', '--keep-aspect-ratio'], default=False, help=_('Maintain picture aspect ratio. Default is to fill the screen.')) - c.add_opt('dont_sharpen', ['-s', '--disable-sharpen'], default=False, + c.add_opt('dont_sharpen', ['-s', '--disable-sharpen'], default=False, help=_('Disable sharpening.')) - c.add_opt('landscape', ['-l', '--landscape'], default=False, + c.add_opt('landscape', ['-l', '--landscape'], default=False, help=_("Don't split landscape images into two portrait images")) + c.add_opt('wide', ['-w', '--wide-aspect'], default=False, + help=_("Keep aspect ratio and scale image using screen height as image width for viewing in landscape mode.")) c.add_opt('right2left', ['--right2left'], default=False, action='store_true', help=_('Used for right-to-left publications like manga. Causes landscape pages to be split into portrait pages from right to left.')) - c.add_opt('no_sort', ['--no-sort'], default=False, + c.add_opt('despeckle', ['-d', '--despeckle'], default=False, + help=_('Enable Despeckle. Reduces speckle noise. May greatly increase processing time.')) + c.add_opt('no_sort', ['--no-sort'], default=False, help=_("Don't sort the files found in the comic alphabetically by name. Instead use the order they were added to the comic.")) - c.add_opt('profile', ['-p', '--profile'], default='prs500', choices=PROFILES.keys(), - help=_('Choose a profile for the device you are generating this LRF for. The default is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s')%PROFILES.keys()) - c.add_opt('verbose', ['--verbose'], default=0, action='count', + c.add_opt('profile', ['-p', '--profile'], default='prs500', choices=PROFILES.keys(), + help=_('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')%PROFILES.keys()) + c.add_opt('verbose', ['-v', '--verbose'], default=0, action='count', help=_('Be verbose, useful for debugging. Can be specified multiple times for greater verbosity.')) - c.add_opt('no_progress_bar', ['--no-progress-bar'], default=False, + c.add_opt('no_progress_bar', ['--no-progress-bar'], default=False, help=_("Don't show progress bar.")) return c @@ -265,9 +320,41 @@ def option_parser(): return c.option_parser(usage=_('''\ %prog [options] comic.cb[z|r] -Convert a comic in a CBZ or CBR file to an LRF ebook. +Convert a comic in a CBZ or CBR file to an ebook. ''')) +def create_epub(pages, profile, opts, thumbnail=None): + wrappers = [] + WRAPPER = textwrap.dedent('''\ + + + Page #%d + + + +
+ comic page #%d +
+ + + ''') + dir = os.path.dirname(pages[0]) + for i, page in enumerate(pages): + wrapper = WRAPPER%(i+1, os.path.basename(page), i+1) + page = os.path.join(dir, 'page_%d.html'%(i+1)) + open(page, 'wb').write(wrapper) + wrappers.append(page) + + mi = MetaInformation(opts.title, [opts.author]) + opf = OPFCreator(dir, mi) + opf.create_manifest([(w, None) for w in wrappers]) + opf.create_spine(wrappers) + metadata = os.path.join(dir, 'metadata.opf') + opf.render(open(metadata, 'wb')) + opts2 = html2epub_config('margin_left=0\nmargin_right=0\nmargin_top=0\nmargin_bottom=0').parse() + opts2.output = opts.output + html2epub(metadata, opts2) + def create_lrf(pages, profile, opts, thumbnail=None): width, height = PROFILES[profile] ps = {} @@ -290,14 +377,15 @@ def create_lrf(pages, profile, opts, thumbnail=None): book.append(_page) book.renderLrf(open(opts.output, 'wb')) + print _('Output written to'), opts.output -def do_convert(path_to_file, opts, notification=lambda m, p: p): + +def do_convert(path_to_file, opts, notification=lambda m, p: p, output_format='lrf'): source = path_to_file if not opts.title: - opts.title = os.path.splitext(os.path.basename(source)) + opts.title = os.path.splitext(os.path.basename(source))[0] if not opts.output: - opts.output = os.path.abspath(os.path.splitext(os.path.basename(source))[0]+'.lrf') - + opts.output = os.path.abspath(os.path.splitext(os.path.basename(source))[0]+'.'+output_format) tdir = extract_comic(source) pages = find_pages(tdir, sort_on_mtime=opts.no_sort, verbose=opts.verbose) if not pages: @@ -312,12 +400,16 @@ def do_convert(path_to_file, opts, notification=lambda m, p: p): thumbnail = os.path.join(tdir2, 'thumbnail.png') if not os.access(thumbnail, os.R_OK): thumbnail = None - create_lrf(pages, opts.profile, opts, thumbnail=thumbnail) + + if output_format == 'lrf': + create_lrf(pages, opts.profile, opts, thumbnail=thumbnail) + else: + create_epub(pages, opts.profile, opts, thumbnail=thumbnail) shutil.rmtree(tdir) shutil.rmtree(tdir2) -def main(args=sys.argv, notification=None): +def main(args=sys.argv, notification=None, output_format='lrf'): parser = option_parser() opts, args = parser.parse_args(args) if len(args) < 2: @@ -331,8 +423,8 @@ def main(args=sys.argv, notification=None): notification = pb.update source = os.path.abspath(args[1]) - do_convert(source, opts, notification) - print _('Output written to'), opts.output + do_convert(source, opts, notification, output_format=output_format) + return 0 if __name__ == '__main__': diff --git a/src/calibre/ebooks/lrf/epub/convert_from.py b/src/calibre/ebooks/lrf/epub/convert_from.py index 110946824b..071a2cb497 100644 --- a/src/calibre/ebooks/lrf/epub/convert_from.py +++ b/src/calibre/ebooks/lrf/epub/convert_from.py @@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal ' import os, sys, shutil, logging from tempfile import mkdtemp from calibre.ebooks.lrf import option_parser as lrf_option_parser -from calibre.ebooks import ConversionError +from calibre.ebooks import ConversionError, DRMError from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file from calibre.ebooks.metadata.opf import OPF from calibre.ebooks.metadata.epub import OCFDirReader @@ -27,6 +27,8 @@ def generate_html(pathtoepub, logger): os.rmdir(tdir) try: ZipFile(pathtoepub).extractall(tdir) + if os.path.exists(os.path.join(tdir, 'META-INF', 'encryption.xml')): + raise DRMError(os.path.basename(pathtoepub)) except: if os.path.exists(tdir) and os.path.isdir(tdir): shutil.rmtree(tdir) diff --git a/src/calibre/ebooks/lrf/fb2/convert_from.py b/src/calibre/ebooks/lrf/fb2/convert_from.py index 27c55757be..dde1ce78e0 100644 --- a/src/calibre/ebooks/lrf/fb2/convert_from.py +++ b/src/calibre/ebooks/lrf/fb2/convert_from.py @@ -1,16 +1,22 @@ +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Anatoly Shipitsin ' """ Convert .fb2 files to .lrf """ -import os, sys, tempfile, shutil, logging +import os, sys, shutil, logging from base64 import b64decode - +from lxml import etree + from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file -from calibre import setup_cli_handlers, __appname__ +from calibre import setup_cli_handlers from calibre.resources import fb2_xsl +from calibre.ptempfile import PersistentTemporaryDirectory +from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.metadata import MetaInformation + def option_parser(): parser = lrf_option_parser( @@ -31,29 +37,42 @@ def extract_embedded_content(doc): data = b64decode(elem.text.strip()) open(fname, 'wb').write(data) -def generate_html(fb2file, encoding, logger): - from lxml import etree - tdir = tempfile.mkdtemp(prefix=__appname__+'_fb2_') - cwd = os.getcwdu() - os.chdir(tdir) +def to_html(fb2file, tdir): + cwd = os.getcwd() try: - logger.info('Parsing XML...') + os.chdir(tdir) + print 'Parsing XML...' parser = etree.XMLParser(recover=True, no_network=True) doc = etree.parse(fb2file, parser) extract_embedded_content(doc) - logger.info('Converting XML to HTML...') + print 'Converting XML to HTML...' styledoc = etree.fromstring(fb2_xsl) - + transform = etree.XSLT(styledoc) result = transform(doc) - html = os.path.join(tdir, 'index.html') - f = open(html, 'wb') - f.write(transform.tostring(result)) - f.close() + open('index.html', 'wb').write(transform.tostring(result)) + try: + mi = get_metadata(open(fb2file, 'rb')) + except: + mi = MetaInformation(None, None) + if not mi.title: + mi.title = os.path.splitext(os.path.basename(fb2file))[0] + if not mi.authors: + mi.authors = [_('Unknown')] + opf = OPFCreator(tdir, mi) + opf.create_manifest([('index.html', None)]) + opf.create_spine(['index.html']) + opf.render(open('metadata.opf', 'wb')) + return os.path.join(tdir, 'metadata.opf') finally: os.chdir(cwd) - return html - + + +def generate_html(fb2file, encoding, logger): + tdir = PersistentTemporaryDirectory('_fb22lrf') + to_html(fb2file, tdir) + return os.path.join(tdir, 'index.html') + def process_file(path, options, logger=None): if logger is None: level = logging.DEBUG if options.verbose else logging.INFO diff --git a/src/calibre/ebooks/lrf/feeds/convert_from.py b/src/calibre/ebooks/lrf/feeds/convert_from.py index 4425877525..6965ea7bf3 100644 --- a/src/calibre/ebooks/lrf/feeds/convert_from.py +++ b/src/calibre/ebooks/lrf/feeds/convert_from.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' ''' @@ -8,12 +8,10 @@ from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf.html.convert_from import process_file from calibre.web.feeds.main import option_parser as feeds_option_parser from calibre.web.feeds.main import run_recipe -from calibre.ptempfile import PersistentTemporaryDirectory -from calibre import sanitize_file_name +from calibre.ptempfile import TemporaryDirectory +from calibre import sanitize_file_name, strftime -import sys, os, time - -import parser +import sys, os def option_parser(): parser = feeds_option_parser() @@ -36,25 +34,25 @@ def main(args=sys.argv, notification=None, handler=None): recipe_arg = args[1] if len(args) > 1 else None - tdir = PersistentTemporaryDirectory('_feeds2lrf') - opts.output_dir = tdir - - recipe = run_recipe(opts, recipe_arg, parser, notification=notification, handler=handler) - - htmlfile = os.path.join(tdir, 'index.html') - if not os.access(htmlfile, os.R_OK): - raise RuntimeError(_('Fetching of recipe failed: ')+recipe_arg) - - lparser = lrf_option_parser('') - ropts = lparser.parse_args(['html2lrf']+recipe.html2lrf_options)[0] - parser.merge_options(ropts, opts) - - if not opts.output: - ext = '.lrs' if opts.lrs else '.lrf' - fname = recipe.title + time.strftime(recipe.timefmt)+ext - opts.output = os.path.join(os.getcwd(), sanitize_file_name(fname)) - print 'Generating LRF...' - process_file(htmlfile, opts) + with TemporaryDirectory('_feeds2lrf') as tdir: + opts.output_dir = tdir + + recipe = run_recipe(opts, recipe_arg, parser, notification=notification, handler=handler) + + htmlfile = os.path.join(tdir, 'index.html') + if not os.access(htmlfile, os.R_OK): + raise RuntimeError(_('Fetching of recipe failed: ')+recipe_arg) + + lparser = lrf_option_parser('') + ropts = lparser.parse_args(['html2lrf']+recipe.html2lrf_options)[0] + parser.merge_options(ropts, opts) + + if not opts.output: + ext = '.lrs' if opts.lrs else '.lrf' + fname = recipe.title + strftime(recipe.timefmt)+ext + opts.output = os.path.join(os.getcwd(), sanitize_file_name(fname)) + print 'Generating LRF...' + process_file(htmlfile, opts) return 0 if __name__ == '__main__': diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index 9ffb9e6398..c8fe27c34a 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -410,6 +410,7 @@ class HTMLConverter(object, LoggingInterface): for key in sel[0].split(','): val = self.parse_style_properties(sel[1]) key = key.strip().lower() + if '+' in key: continue if ':' in key: key, sep, pseudo = key.partition(':') if key in pdict: @@ -437,7 +438,7 @@ class HTMLConverter(object, LoggingInterface): for s in props.split(';'): l = s.split(':',1) if len(l)==2: - key = str(l[0].strip()).lower() + key = l[0].strip().lower() val = l[1].strip() prop [key] = val return prop @@ -539,7 +540,7 @@ class HTMLConverter(object, LoggingInterface): return tb for page in list(self.book.pages()[index+1:]): for c in page.contents: - if isinstance(c, (TextBlock, ImageBlock)): + if isinstance(c, (TextBlock, ImageBlock, Canvas)): return c raise ConversionError(_('Could not parse file: %s')%self.file_name) @@ -667,10 +668,12 @@ class HTMLConverter(object, LoggingInterface): ascii_text = item.text if not item.fragment and item.abspath in self.tops: self.book.addTocEntry(ascii_text, self.tops[item.abspath]) - else: - url = item.abspath+item.fragment + elif item.abspath: + url = item.abspath+(item.fragment if item.fragment else '') if url in self.targets: self.book.addTocEntry(ascii_text, self.targets[url]) + + def end_page(self): @@ -777,11 +780,11 @@ class HTMLConverter(object, LoggingInterface): @param css: A dict ''' src = tag.string if hasattr(tag, 'string') else tag - if len(src) > 32767: + if len(src) > 32760: pos = 0 while pos < len(src): - self.add_text(src[pos:pos+32767], css, pseudo_css, force_span_use) - pos += 32767 + self.add_text(src[pos:pos+32760], css, pseudo_css, force_span_use) + pos += 32760 return src = src.replace('\r\n', '\n').replace('\r', '\n') @@ -1446,10 +1449,11 @@ class HTMLConverter(object, LoggingInterface): pass if not self.disable_chapter_detection and \ (self.chapter_attr[0].match(tagname) and \ - tag.has_key(self.chapter_attr[1]) and \ - self.chapter_attr[2].match(tag[self.chapter_attr[1]])): + (self.chapter_attr[1].lower() == 'none' or \ + (tag.has_key(self.chapter_attr[1]) and \ + self.chapter_attr[2].match(tag[self.chapter_attr[1]])))): self.log_debug('Detected chapter %s', tagname) - self.end_page() + self.end_page() self.page_break_found = True if self.options.add_chapters_to_toc: @@ -1562,6 +1566,10 @@ class HTMLConverter(object, LoggingInterface): if tagname == 'ol': old_counter = self.list_counter self.list_counter = 1 + try: + self.list_counter = int(tag['start']) + except: + pass prev_bs = self.current_block.blockStyle self.end_current_block() attrs = self.current_block.blockStyle.attrs @@ -1749,7 +1757,7 @@ class HTMLConverter(object, LoggingInterface): try: self.process_table(tag, tag_css) except Exception, err: - self.log_warning(_('An error occurred while processing a table: %s. Ignoring table markup.'), str(err)) + self.log_warning(_('An error occurred while processing a table: %s. Ignoring table markup.'), unicode(err)) self.log_debug('', exc_info=True) self.log_debug(_('Bad table:\n%s'), str(tag)[:300]) self.in_table = False diff --git a/src/calibre/ebooks/lrf/html/demo/demo.html b/src/calibre/ebooks/lrf/html/demo/demo.html index 9fa73bcfac..8a43b50708 100644 --- a/src/calibre/ebooks/lrf/html/demo/demo.html +++ b/src/calibre/ebooks/lrf/html/demo/demo.html @@ -11,7 +11,7 @@

Demo of html2lrf

- This document contains a demonstration of the capabilities of html2lrf, the HTML to LRF converter from libprs500. To obtain libprs500 visit
https://libprs500.kovidgoyal.net + This document contains a demonstration of the capabilities of html2lrf, the HTML to LRF converter from calibre. To obtain calibre visit
http://calibre.kovidgoyal.net


Table of Contents

diff --git a/src/calibre/ebooks/lrf/meta.py b/src/calibre/ebooks/lrf/meta.py index 9996b2be84..cac7ea9cc2 100644 --- a/src/calibre/ebooks/lrf/meta.py +++ b/src/calibre/ebooks/lrf/meta.py @@ -676,7 +676,10 @@ def main(args=sys.argv): if options.get_thumbnail: print "Thumbnail:", td if options.get_cover: - ext, data = lrf.get_cover() + try: + ext, data = lrf.get_cover() + except: # Fails on books created by LRFCreator 1.0 + ext, data = None, None if data: cover = os.path.splitext(os.path.basename(args[1]))[0]+"_cover."+ext open(cover, 'wb').write(data) diff --git a/src/calibre/ebooks/lrf/pdf/convert_from.py b/src/calibre/ebooks/lrf/pdf/convert_from.py index 1d1260de2c..ac9c4b3ade 100644 --- a/src/calibre/ebooks/lrf/pdf/convert_from.py +++ b/src/calibre/ebooks/lrf/pdf/convert_from.py @@ -5,10 +5,13 @@ __copyright__ = '2008, Kovid Goyal ' import sys, os, subprocess, logging from functools import partial from calibre import isosx, setup_cli_handlers, filename_to_utf8, iswindows, islinux -from calibre.ebooks import ConversionError +from calibre.ebooks import ConversionError, DRMError from calibre.ptempfile import PersistentTemporaryDirectory from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.metadata.pdf import get_metadata PDFTOHTML = 'pdftohtml' popen = subprocess.Popen @@ -20,7 +23,7 @@ if iswindows and hasattr(sys, 'frozen'): if islinux and getattr(sys, 'frozen_path', False): PDFTOHTML = os.path.join(getattr(sys, 'frozen_path'), 'pdftohtml') -def generate_html(pathtopdf, logger): +def generate_html(pathtopdf, tdir): ''' Convert the pdf into html. @return: Path to a temporary file containing the HTML. @@ -29,10 +32,10 @@ def generate_html(pathtopdf, logger): pathtopdf = pathtopdf.encode(sys.getfilesystemencoding()) if not os.access(pathtopdf, os.R_OK): raise ConversionError, 'Cannot read from ' + pathtopdf - tdir = PersistentTemporaryDirectory('pdftohtml') index = os.path.join(tdir, 'index.html') # This is neccessary as pdftohtml doesn't always (linux) respect absolute paths - cmd = (PDFTOHTML, '-enc', 'UTF-8', '-noframes', '-p', '-nomerge', pathtopdf, os.path.basename(index)) + pathtopdf = os.path.abspath(pathtopdf) + cmd = (PDFTOHTML, '-enc', 'UTF-8', '-noframes', '-p', '-nomerge', pathtopdf, os.path.basename(index)) cwd = os.getcwd() try: @@ -44,16 +47,30 @@ def generate_html(pathtopdf, logger): raise ConversionError(_('Could not find pdftohtml, check it is in your PATH'), True) else: raise - logger.info(p.stdout.read()) + print p.stdout.read() ret = p.wait() if ret != 0: err = p.stderr.read() raise ConversionError, err if not os.path.exists(index) or os.stat(index).st_size < 100: - raise ConversionError(os.path.basename(pathtopdf) + _(' does not allow copying of text.'), True) - raw = open(index).read(4000) - if not '\n'+raw) + if not ' 65535: diff --git a/src/calibre/ebooks/lrf/pylrs/pylrs.py b/src/calibre/ebooks/lrf/pylrs/pylrs.py index a8cbb6fb1c..9fcf0ef624 100644 --- a/src/calibre/ebooks/lrf/pylrs/pylrs.py +++ b/src/calibre/ebooks/lrf/pylrs/pylrs.py @@ -603,7 +603,7 @@ class Book(Delegator): def renderLrs(self, lrsFile, encoding="UTF-8"): - if isinstance(lrsFile, basestring): + if isinstance(lrsFile, basestring): lrsFile = codecs.open(lrsFile, "wb", encoding=encoding) self.render(lrsFile, outputEncodingName=encoding) lrsFile.close() diff --git a/src/calibre/ebooks/lrf/rtf/convert_from.py b/src/calibre/ebooks/lrf/rtf/convert_from.py index 1fd8314c96..9c3a06f403 100644 --- a/src/calibre/ebooks/lrf/rtf/convert_from.py +++ b/src/calibre/ebooks/lrf/rtf/convert_from.py @@ -1,19 +1,20 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import os, sys, tempfile, subprocess, shutil, logging, glob +import os, sys, shutil, logging, glob + +from lxml import etree from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file -from calibre.ebooks import ConversionError -from calibre import isosx, setup_cli_handlers, __appname__ +from calibre import setup_cli_handlers from calibre.libwand import convert, WandException from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup from calibre.ebooks.lrf.rtf.xsl import xhtml - -UNRTF = 'unrtf' -if isosx and hasattr(sys, 'frameworks_dir'): - UNRTF = os.path.join(getattr(sys, 'frameworks_dir'), UNRTF) +from calibre.ebooks.rtf2xml.ParseRtf import RtfInvalidCodeException +from calibre.ptempfile import PersistentTemporaryDirectory +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf import OPFCreator def option_parser(): parser = lrf_option_parser( @@ -37,32 +38,6 @@ def convert_images(html, logger): continue return html -def generate_html(rtfpath, logger): - tdir = tempfile.mkdtemp(prefix=__appname__+'_') - cwd = os.path.abspath(os.getcwd()) - os.chdir(tdir) - try: - logger.info('Converting to HTML...') - sys.stdout.flush() - handle, path = tempfile.mkstemp(dir=tdir, suffix='.html') - file = os.fdopen(handle, 'wb') - cmd = ' '.join([UNRTF, '"'+rtfpath+'"']) - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - raw = p.stdout.read() - ret = p.wait() - if ret != 0: - if len(raw) > 1000: #unrtf crashes occassionally on OSX and windows but still convert correctly - raw += '\n' - else: - logger.critical(p.stderr.read()) - raise ConversionError, 'unrtf failed with error code: %d'%(ret,) - file.write(convert_images(raw, logger)) - file.close() - return path - finally: - os.chdir(cwd) - def process_file(path, options, logger=None): if logger is None: level = logging.DEBUG if options.verbose else logging.INFO @@ -72,8 +47,8 @@ def process_file(path, options, logger=None): f = open(rtf, 'rb') mi = get_metadata(f, 'rtf') f.close() - html = generate_html2(rtf, logger) - tdir = os.path.dirname(html) + tdir = PersistentTemporaryDirectory('_rtf2lrf') + html = generate_html(rtf, tdir) cwd = os.getcwdu() try: if not options.output: @@ -111,12 +86,12 @@ def main(args=sys.argv, logger=None): return 0 -def generate_xml(rtfpath): +def generate_xml(rtfpath, tdir): from calibre.ebooks.rtf2xml.ParseRtf import ParseRtf - tdir = tempfile.mkdtemp(prefix=__appname__+'_') ofile = os.path.join(tdir, 'index.xml') cwd = os.getcwdu() os.chdir(tdir) + rtfpath = os.path.abspath(rtfpath) try: parser = ParseRtf( in_file = rtfpath, @@ -162,24 +137,27 @@ def generate_xml(rtfpath): return ofile -def generate_html2(rtfpath, logger): - from lxml import etree - logger.info('Converting RTF to XML...') - xml = generate_xml(rtfpath) +def generate_html(rtfpath, tdir): + print 'Converting RTF to XML...' + rtfpath = os.path.abspath(rtfpath) + try: + xml = generate_xml(rtfpath, tdir) + except RtfInvalidCodeException: + raise Exception(_('This RTF file has a feature calibre does not support. Convert it to HTML and then convert it.')) tdir = os.path.dirname(xml) cwd = os.getcwdu() os.chdir(tdir) try: - logger.info('Parsing XML...') + print 'Parsing XML...' parser = etree.XMLParser(recover=True, no_network=True) try: doc = etree.parse(xml, parser) except: raise - logger.info('Parsing failed. Trying to clean up XML...') + print 'Parsing failed. Trying to clean up XML...' soup = BeautifulStoneSoup(open(xml, 'rb').read()) doc = etree.fromstring(str(soup)) - logger.info('Converting XML to HTML...') + print 'Converting XML to HTML...' styledoc = etree.fromstring(xhtml) transform = etree.XSLT(styledoc) @@ -187,8 +165,22 @@ def generate_html2(rtfpath, logger): tdir = os.path.dirname(xml) html = os.path.join(tdir, 'index.html') f = open(html, 'wb') - f.write(transform.tostring(result)) + res = transform.tostring(result) + res = res[:100].replace('xmlns:html', 'xmlns') + res[100:] + f.write(res) f.close() + try: + mi = get_metadata(open(rtfpath, 'rb')) + except: + mi = MetaInformation(None, None) + if not mi.title: + mi.title = os.path.splitext(os.path.basename(rtfpath))[0] + if not mi.authors: + mi.authors = [_('Unknown')] + opf = OPFCreator(tdir, mi) + opf.create_manifest([('index.html', None)]) + opf.create_spine(['index.html']) + opf.render(open('metadata.opf', 'wb')) finally: os.chdir(cwd) return html diff --git a/src/calibre/ebooks/lrf/txt/convert_from.py b/src/calibre/ebooks/lrf/txt/convert_from.py index 885f271538..32bb329603 100644 --- a/src/calibre/ebooks/lrf/txt/convert_from.py +++ b/src/calibre/ebooks/lrf/txt/convert_from.py @@ -5,12 +5,14 @@ Convert .txt files to .lrf """ import os, sys, codecs, logging -from calibre.ptempfile import PersistentTemporaryFile +from calibre.ptempfile import PersistentTemporaryDirectory from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks import ConversionError from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file from calibre.ebooks.markdown import markdown from calibre import setup_cli_handlers +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf import OPFCreator def option_parser(): parser = lrf_option_parser( @@ -23,7 +25,7 @@ _('''%prog [options] mybook.txt return parser -def generate_html(txtfile, encoding, logger): +def generate_html(txtfile, encoding, tdir): ''' Convert txtfile to html and return a PersistentTemporaryFile object pointing to the file with the HTML. @@ -44,15 +46,19 @@ def generate_html(txtfile, encoding, logger): else: txt = codecs.open(txtfile, 'rb', enc).read() - logger.info('Converting text to HTML...') + print 'Converting text to HTML...' md = markdown.Markdown( extensions=['footnotes', 'tables', 'toc'], safe_mode=False, ) - html = md.convert(txt) - p = PersistentTemporaryFile('.html', dir=os.path.dirname(txtfile)) - p.close() - codecs.open(p.name, 'wb', 'utf8').write(html) + html = ''+md.convert(txt)+'' + p = os.path.join(tdir, 'index.html') + open(p, 'wb').write(html.encode('utf-8')) + mi = MetaInformation(os.path.splitext(os.path.basename(txtfile))[0], [_('Unknown')]) + opf = OPFCreator(tdir, mi) + opf.create_manifest([(os.path.join(tdir, 'index.html'), None)]) + opf.create_spine([os.path.join(tdir, 'index.html')]) + opf.render(open(os.path.join(tdir, 'metadata.opf'), 'wb')) return p def process_file(path, options, logger=None): @@ -63,7 +69,8 @@ def process_file(path, options, logger=None): txt = os.path.abspath(os.path.expanduser(path)) if not hasattr(options, 'debug_html_generation'): options.debug_html_generation = False - htmlfile = generate_html(txt, options.encoding, logger) + tdir = PersistentTemporaryDirectory('_txt2lrf') + htmlfile = generate_html(txt, options.encoding, tdir) options.encoding = 'utf-8' if not options.debug_html_generation: options.force_page_break = 'h2' @@ -73,9 +80,9 @@ def process_file(path, options, logger=None): options.output = os.path.abspath(os.path.expanduser(options.output)) if not options.title: options.title = os.path.splitext(os.path.basename(path))[0] - html_process_file(htmlfile.name, options, logger) + html_process_file(htmlfile, options, logger) else: - print open(htmlfile.name, 'rb').read() + print open(htmlfile, 'rb').read() def main(args=sys.argv, logger=None): parser = option_parser() diff --git a/src/calibre/ebooks/lrf/web/convert_from.py b/src/calibre/ebooks/lrf/web/convert_from.py index 6bd2eaf3e5..ca523e869b 100644 --- a/src/calibre/ebooks/lrf/web/convert_from.py +++ b/src/calibre/ebooks/lrf/web/convert_from.py @@ -2,10 +2,10 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''Convert websites into LRF files.''' -import sys, time, tempfile, shutil, os, logging, imp, inspect, re +import sys, tempfile, shutil, os, logging, imp, inspect, re from urlparse import urlsplit -from calibre import __appname__, setup_cli_handlers, CommandLineError +from calibre import __appname__, setup_cli_handlers, CommandLineError, strftime from calibre.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf.html.convert_from import process_file @@ -128,7 +128,7 @@ def process_profile(args, options, logger=None): title = profile.title if not title: title = urlsplit(options.url).netloc - options.title = title + time.strftime(profile.timefmt, time.localtime()) + options.title = title + strftime(profile.timefmt) options.match_regexps += profile.match_regexps options.preprocess_regexps = profile.preprocess_regexps diff --git a/src/calibre/ebooks/lrf/web/profiles/ap.py b/src/calibre/ebooks/lrf/web/profiles/ap.py index d98adb6ddd..161699941a 100644 --- a/src/calibre/ebooks/lrf/web/profiles/ap.py +++ b/src/calibre/ebooks/lrf/web/profiles/ap.py @@ -30,7 +30,7 @@ class AssociatedPress(DefaultProfile): ('AP US News', 'http://hosted.ap.org/lineups/USHEADS-rss_2.0.xml?SITE=CAVIC&SECTION=HOME'), ('AP World News', 'http://hosted.ap.org/lineups/WORLDHEADS-rss_2.0.xml?SITE=SCAND&SECTION=HOME'), ('AP Political News', 'http://hosted.ap.org/lineups/POLITICSHEADS-rss_2.0.xml?SITE=ORMED&SECTION=HOME'), - ('AP Washington News', 'http://hosted.ap.org/lineups/WASHINGTONHEADS-rss_2.0.xml?SITE=NYPLA&SECTION=HOME'), + ('AP Washington State News', 'http://hosted.ap.org/lineups/WASHINGTONHEADS-rss_2.0.xml?SITE=NYPLA&SECTION=HOME'), ('AP Technology News', 'http://hosted.ap.org/lineups/TECHHEADS-rss_2.0.xml?SITE=CTNHR&SECTION=HOME'), ('AP Health News', 'http://hosted.ap.org/lineups/HEALTHHEADS-rss_2.0.xml?SITE=FLDAY&SECTION=HOME'), ('AP Science News', 'http://hosted.ap.org/lineups/SCIENCEHEADS-rss_2.0.xml?SITE=OHCIN&SECTION=HOME'), diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index c9468c812e..26d52cc3f2 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -15,6 +15,24 @@ from calibre.constants import __version__ as VERSION from calibre import relpath from calibre.utils.config import OptionParser +def string_to_authors(raw): + raw = raw.replace('&&', u'\uffff') + authors = [a.strip().replace(u'\uffff', '&') for a in raw.split('&')] + return authors + +def authors_to_string(authors): + return ' & '.join([a.replace('&', '&&') for a in authors]) + +def author_to_author_sort(author): + tokens = author.split() + tokens = tokens[-1:] + tokens[:-1] + if len(tokens) > 1: + tokens[0] += ',' + return ' '.join(tokens) + +def authors_to_sort_string(authors): + return ' & '.join(map(author_to_author_sort, authors)) + def get_parser(extension): ''' Return an option parser with the basic metadata options already setup''' parser = OptionParser(usage='%prog [options] myfile.'+extension+'\n\nRead and write metadata from an ebook file.') @@ -43,7 +61,7 @@ class Resource(object): def __init__(self, href_or_path, basedir=os.getcwd(), is_path=True): self._href = None - self._basedir = None + self._basedir = basedir self.path = None self.fragment = '' try: @@ -55,7 +73,7 @@ class Resource(object): if is_path: path = href_or_path if not os.path.isabs(path): - path = os.path.abspath(os.path.join(path, basedir)) + path = os.path.abspath(os.path.join(basedir, path)) if isinstance(path, str): path = path.decode(sys.getfilesystemencoding()) self.path = path @@ -141,6 +159,10 @@ class ResourceCollection(object): 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): @@ -167,18 +189,17 @@ class MetaInformation(object): for attr in ('author_sort', 'title_sort', 'comments', 'category', 'publisher', 'series', 'series_index', 'rating', 'isbn', 'tags', 'cover_data', 'application_id', 'guide', - 'manifest', 'spine', 'toc', 'cover', 'language'): + 'manifest', 'spine', 'toc', 'cover', 'language', 'book_producer'): if hasattr(mi, attr): setattr(ans, attr, getattr(mi, attr)) - def __init__(self, title, authors=[_('Unknown')]): ''' @param title: title or "Unknown" or a MetaInformation object @param authors: List of strings or [] ''' mi = None - if isinstance(title, MetaInformation): + if hasattr(title, 'title') and hasattr(title, 'authors'): mi = title title = mi.title authors = mi.authors @@ -186,42 +207,32 @@ class MetaInformation(object): self.author = authors # Needed for backward compatibility #: List of strings or [] self.authors = authors - #: Sort text for author - self.author_sort = None if not mi else mi.author_sort - self.title_sort = None if not mi else mi.title_sort - self.comments = None if not mi else mi.comments - self.category = None if not mi else mi.category - self.publisher = None if not mi else mi.publisher - self.series = None if not mi else mi.series - self.series_index = None if not mi else mi.series_index - self.rating = None if not mi else mi.rating - self.isbn = None if not mi else mi.isbn - self.tags = [] if not mi else mi.tags - self.language = None if not mi else mi.language # Typically a string describing the language + self.tags = getattr(mi, 'tags', []) #: mi.cover_data = (ext, data) - self.cover_data = mi.cover_data if (mi and hasattr(mi, 'cover_data')) else (None, None) - self.application_id = mi.application_id if (mi and hasattr(mi, 'application_id')) else None - self.manifest = getattr(mi, 'manifest', None) - self.toc = getattr(mi, 'toc', None) - self.spine = getattr(mi, 'spine', None) - self.guide = getattr(mi, 'guide', None) - self.cover = getattr(mi, 'cover', None) + self.cover_data = getattr(mi, 'cover_data', (None, None)) + + for x in ('author_sort', 'title_sort', 'comments', 'category', 'publisher', + 'series', 'series_index', 'rating', 'isbn', 'language', + 'application_id', 'manifest', 'toc', 'spine', 'guide', 'cover', + 'book_producer', + ): + setattr(self, x, getattr(mi, x, None)) def smart_update(self, mi): ''' Merge the information in C{mi} into self. In case of conflicts, the information in C{mi} takes precedence, unless the information in mi is NULL. ''' - if mi.title and mi.title.lower() != 'unknown': + if mi.title and mi.title != _('Unknown'): self.title = mi.title - if mi.authors and mi.authors[0].lower() != 'unknown': + if mi.authors and mi.authors[0] != _('Unknown'): self.authors = mi.authors for attr in ('author_sort', 'title_sort', 'comments', 'category', 'publisher', 'series', 'series_index', 'rating', 'isbn', 'application_id', 'manifest', 'spine', 'toc', - 'cover', 'language', 'guide'): + 'cover', 'language', 'guide', 'book_producer'): if hasattr(mi, attr): val = getattr(mi, attr) if val is not None: @@ -242,6 +253,8 @@ class MetaInformation(object): ans += ((' (' + self.author_sort + ')') if self.author_sort else '') + u'\n' if self.publisher: ans += u'Publisher: '+ unicode(self.publisher) + u'\n' + if self.book_producer: + ans += u'Producer : '+ unicode(self.book_producer) + u'\n' if self.category: ans += u'Category : ' + unicode(self.category) + u'\n' if self.comments: diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index 44eaedaf26..25f74b99c9 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -6,14 +6,14 @@ __copyright__ = '2008, Kovid Goyal ' '''Read meta information from epub files''' import sys, os - -from calibre.utils.zipfile import ZipFile, BadZipfile from cStringIO import StringIO from contextlib import closing + +from calibre.utils.zipfile import ZipFile, BadZipfile, safe_replace from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup -from calibre.ebooks.metadata.opf import OPF, OPFReader, OPFCreator from calibre.ebooks.metadata import get_parser, MetaInformation +from calibre.ebooks.metadata.opf2 import OPF class EPubException(Exception): pass @@ -43,20 +43,22 @@ class Container(dict): raise EPubException(" element malformed") class OCF(object): - MIMETYPE = 'application/epub+zip' - CONTAINER_PATH = 'META-INF/container.xml' + MIMETYPE = 'application/epub+zip' + CONTAINER_PATH = 'META-INF/container.xml' + ENCRYPTION_PATH = 'META-INF/encryption.xml' def __init__(self): raise NotImplementedError('Abstract base class') + class OCFReader(OCF): def __init__(self): try: mimetype = self.open('mimetype').read().rstrip() if mimetype != OCF.MIMETYPE: - raise EPubException - except (KeyError, EPubException): - raise EPubException("not an .epub OCF container") + print 'WARNING: Invalid mimetype declaration', mimetype + except: + print 'WARNING: Epub doesn\'t contain a mimetype declaration' try: with closing(self.open(OCF.CONTAINER_PATH)) as f: @@ -66,35 +68,27 @@ class OCFReader(OCF): try: with closing(self.open(self.container[OPF.MIMETYPE])) as f: - self.opf = OPFReader(f, self.root) + self.opf = OPF(f, self.root) except KeyError: raise EPubException("missing OPF package file") + class OCFZipReader(OCFReader): - def __init__(self, stream, mode='r'): + def __init__(self, stream, mode='r', root=None): try: - self.archive = ZipFile(stream, mode) + self.archive = ZipFile(stream, mode=mode) except BadZipfile: raise EPubException("not a ZIP .epub OCF container") - self.root = getattr(stream, 'name', os.getcwd()) + self.root = root + if self.root is None: + self.root = os.getcwdu() + if hasattr(stream, 'name'): + self.root = os.path.abspath(os.path.dirname(stream.name)) super(OCFZipReader, self).__init__() def open(self, name, mode='r'): return StringIO(self.archive.read(name)) -class OCFZipWriter(OCFZipReader): - - def __init__(self, stream): - OCFZipReader.__init__(self, stream, mode='a') - - def set_metadata(self, mi): - name = self.container[OPF.MIMETYPE] - stream = StringIO() - opf = OPFCreator(self.root, mi) - opf.render(stream) - self.archive.delete(name) - self.archive.writestr(name, stream.getvalue()) - class OCFDirReader(OCFReader): def __init__(self, path): self.root = path @@ -109,12 +103,22 @@ def get_metadata(stream): return OCFZipReader(stream).opf def set_metadata(stream, mi): - OCFZipWriter(stream).set_metadata(mi) - + reader = OCFZipReader(stream, root=os.getcwdu()) + reader.opf.smart_update(mi) + newopf = StringIO(reader.opf.render()) + safe_replace(stream, reader.container[OPF.MIMETYPE], newopf) + def option_parser(): parser = get_parser('epub') parser.remove_option('--category') - parser.add_option('--tags', default=None, help=_('A comma separated list of tags to set')) + parser.add_option('--tags', default=None, + help=_('A comma separated list of tags to set')) + parser.add_option('--series', default=None, + help=_('The series to which this book belongs')) + parser.add_option('--series-index', default=None, + help=_('The series index')) + parser.add_option('--language', default=None, + help=_('The book language')) return parser def main(args=sys.argv): @@ -124,19 +128,36 @@ def main(args=sys.argv): parser.print_help() return 1 stream = open(args[1], 'r+b') - mi = MetaInformation(OCFZipReader(stream).opf) + mi = MetaInformation(OCFZipReader(stream, root=os.getcwdu()).opf) + changed = False if opts.title: mi.title = opts.title + changed = True if opts.authors: mi.authors = opts.authors.split(',') + changed = True if opts.tags: mi.tags = opts.tags.split(',') + changed = True if opts.comment: mi.comments = opts.comment - - set_metadata(stream, mi) - - print unicode(mi) + changed = True + if opts.series: + mi.series = opts.series + changed = True + if opts.series_index: + mi.series_index = opts.series_index + changed = True + if opts.language is not None: + mi.language = opts.language + changed = True + + if changed: + stream.seek(0) + set_metadata(stream, mi) + stream.seek(0) + print unicode(MetaInformation(OCFZipReader(stream, root=os.getcwdu()).opf)) + stream.close() return 0 if __name__ == '__main__': diff --git a/src/calibre/ebooks/metadata/fb2.py b/src/calibre/ebooks/metadata/fb2.py index f66a25e703..1458a02f37 100644 --- a/src/calibre/ebooks/metadata/fb2.py +++ b/src/calibre/ebooks/metadata/fb2.py @@ -33,8 +33,8 @@ def get_metadata(stream): exts = ['.jpg'] cdata = (exts[0][1:], b64decode(binary.string.strip())) - if comments and len(comments) > 1: - comments = comments.p.contents[0] + if comments: + comments = u''.join(comments.findAll(text=True)) series = soup.find("sequence") mi = MetaInformation(title, author) mi.comments = comments diff --git a/src/calibre/ebooks/metadata/imp.py b/src/calibre/ebooks/metadata/imp.py new file mode 100644 index 0000000000..e9d122a396 --- /dev/null +++ b/src/calibre/ebooks/metadata/imp.py @@ -0,0 +1,62 @@ +__license__ = 'GPL v3' +__copyright__ = '2008, Ashish Kulkarni ' +'''Read meta information from IMP files''' + +import sys, os + +from calibre.ebooks.metadata import MetaInformation + +MAGIC = ['\x00\x01BOOKDOUG', '\x00\x02BOOKDOUG'] + +def get_metadata(stream): + """ Return metadata as a L{MetaInfo} object """ + title = 'Unknown' + mi = MetaInformation(title, ['Unknown']) + stream.seek(0) + try: + if stream.read(10) not in MAGIC: + print >>sys.stderr, u'Couldn\'t read IMP header from file' + return mi + + def cString(skip=0): + result = '' + while 1: + data = stream.read(1) + if data == '\x00': + if not skip: return result + skip -= 1 + result, data = '', '' + result += data + + stream.read(38) # skip past some uninteresting headers + _, category, title, author = cString(), cString(), cString(1), cString(2) + + if title: + mi.title = title + if author: + src = author.split('&') + authors = [] + for au in src: + authors += au.split(',') + mi.authors = authors + mi.author = author + if category: + mi.category = category + except Exception, err: + msg = u'Couldn\'t read metadata from imp: %s with error %s'%(mi.title, unicode(err)) + print >>sys.stderr, msg.encode('utf8') + return mi + + +def main(args=sys.argv): + if len(args) != 2: + print >>sys.stderr, _('Usage: imp-meta file.imp') + print >>sys.stderr, _('No filename specified.') + return 1 + + path = os.path.abspath(os.path.expanduser(args[1])) + print get_metadata(open(path, 'rb')) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/metadata/library_thing.py b/src/calibre/ebooks/metadata/library_thing.py index f93ffafd66..fdecf3fa99 100644 --- a/src/calibre/ebooks/metadata/library_thing.py +++ b/src/calibre/ebooks/metadata/library_thing.py @@ -39,7 +39,7 @@ def cover_from_isbn(isbn, timeout=5.): _timeout = socket.getdefaulttimeout() socket.setdefaulttimeout(timeout) try: - src = browser.open('http://www.librarything.com/isbn/'+isbn).read() + src = browser.open('http://www.librarything.com/isbn/'+isbn).read().decode('utf-8', 'replace') s = BeautifulSoup(src) url = s.find('td', attrs={'class':'left'}) if url is None: diff --git a/src/calibre/ebooks/metadata/meta.py b/src/calibre/ebooks/metadata/meta.py index 35d89a51be..8da74ceb8f 100644 --- a/src/calibre/ebooks/metadata/meta.py +++ b/src/calibre/ebooks/metadata/meta.py @@ -9,9 +9,12 @@ from calibre.ebooks.metadata.fb2 import get_metadata as fb2_metadata from calibre.ebooks.lrf.meta import get_metadata as lrf_metadata from calibre.ebooks.metadata.pdf import get_metadata as pdf_metadata from calibre.ebooks.metadata.lit import get_metadata as lit_metadata +from calibre.ebooks.metadata.imp import get_metadata as imp_metadata +from calibre.ebooks.metadata.rb import get_metadata as rb_metadata from calibre.ebooks.metadata.epub import get_metadata as epub_metadata from calibre.ebooks.metadata.html import get_metadata as html_metadata from calibre.ebooks.mobi.reader import get_metadata as mobi_metadata +from calibre.ebooks.metadata.odt import get_metadata as odt_metadata from calibre.ebooks.metadata.opf import OPFReader from calibre.ebooks.metadata.rtf import set_metadata as set_rtf_metadata from calibre.ebooks.lrf.meta import set_metadata as set_lrf_metadata @@ -21,8 +24,8 @@ from calibre.ebooks.metadata import MetaInformation _METADATA_PRIORITIES = [ 'html', 'htm', 'xhtml', 'xhtm', - 'rtf', 'fb2', 'pdf', 'prc', - 'epub', 'lit', 'lrf', 'mobi', + 'rtf', 'fb2', 'pdf', 'prc', 'odt', + 'epub', 'lit', 'lrf', 'mobi', 'rb', 'imp' ] # The priorities for loading metadata from different file types @@ -41,23 +44,28 @@ def metadata_from_formats(formats): for path in formats: ext = path_to_ext(path) stream = open(path, 'rb') - mi.smart_update(get_metadata(stream, stream_type=ext, use_libprs_metadata=True)) + try: + mi.smart_update(get_metadata(stream, stream_type=ext, use_libprs_metadata=True)) + except: + continue if getattr(mi, 'application_id', None) is not None: return mi if not mi.title: - mi.title = 'Unknown' + mi.title = _('Unknown') if not mi.authors: - mi.authors = ['Unknown'] + mi.authors = [_('Unknown')] return mi def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False): if stream_type: stream_type = stream_type.lower() - if stream_type in ('html', 'html', 'xhtml', 'xhtm'): + if stream_type in ('html', 'html', 'xhtml', 'xhtm', 'xml'): stream_type = 'html' if stream_type in ('mobi', 'prc'): stream_type = 'mobi' + if stream_type in ('odt', 'ods', 'odp', 'odg', 'odf'): + stream_type = 'odt' opf = None if hasattr(stream, 'name'): @@ -68,18 +76,20 @@ def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False): if use_libprs_metadata and getattr(opf, 'application_id', None) is not None: return opf - try: - func = eval(stream_type + '_metadata') - mi = func(stream) - except NameError: - mi = MetaInformation(None, None) + mi = MetaInformation(None, None) + if prefs['read_file_metadata']: + try: + func = eval(stream_type + '_metadata') + mi = func(stream) + except NameError: + pass name = os.path.basename(getattr(stream, 'name', '')) base = metadata_from_filename(name) if not base.authors: - base.authors = ['Unknown'] + base.authors = [_('Unknown')] if not base.title: - base.title = 'Unknown' + base.title = _('Unknown') base.smart_update(mi) if opf is not None: base.smart_update(opf) diff --git a/src/calibre/ebooks/metadata/ncx.xml b/src/calibre/ebooks/metadata/ncx.xml index 68971f63f1..55395805cd 100644 --- a/src/calibre/ebooks/metadata/ncx.xml +++ b/src/calibre/ebooks/metadata/ncx.xml @@ -1,7 +1,10 @@ + + @@ -14,11 +17,11 @@ Table of Contents - ${'%*s'%(4*level,'')} + ${'%*s'%(4*level,'')} ${'%*s'%(4*level,'')} ${'%*s'%(4*level,'')}${np.text} ${'%*s'%(4*level,'')} - ${'%*s'%(4*level,'')} + ${'%*s'%(4*level,'')} ${navpoint(np2, level+1)} ${'%*s'%(4*level,'')} diff --git a/src/calibre/ebooks/metadata/odt.py b/src/calibre/ebooks/metadata/odt.py new file mode 100755 index 0000000000..904c07ef2a --- /dev/null +++ b/src/calibre/ebooks/metadata/odt.py @@ -0,0 +1,266 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +import zipfile, sys, re +import xml.sax.saxutils +from cStringIO import StringIO + +from odf.namespaces import OFFICENS, DCNS, METANS +from calibre.ebooks.metadata import MetaInformation, string_to_authors + +whitespace = re.compile(r'\s+') + +fields = { +'title': (DCNS,u'title'), +'description': (DCNS,u'description'), +'subject': (DCNS,u'subject'), +'creator': (DCNS,u'creator'), +'date': (DCNS,u'date'), +'language': (DCNS,u'language'), +'generator': (METANS,u'generator'), +'initial-creator': (METANS,u'initial-creator'), +'keyword': (METANS,u'keyword'), +'editing-duration': (METANS,u'editing-duration'), +'editing-cycles': (METANS,u'editing-cycles'), +'printed-by': (METANS,u'printed-by'), +'print-date': (METANS,u'print-date'), +'creation-date': (METANS,u'creation-date'), +'user-defined': (METANS,u'user-defined'), +#'template': (METANS,u'template'), +} + +def normalize(str): + """ + The normalize-space function returns the argument string with whitespace + normalized by stripping leading and trailing whitespace and replacing + sequences of whitespace characters by a single space. + """ + return whitespace.sub(' ', str).strip() + +class MetaCollector: + """ + The MetaCollector is a pseudo file object, that can temporarily ignore write-calls + It could probably be replaced with a StringIO object. + """ + def __init__(self): + self._content = [] + self.dowrite = True + + def write(self, str): + if self.dowrite: + self._content.append(str) + + def content(self): + return ''.join(self._content) + + +class odfmetaparser(xml.sax.saxutils.XMLGenerator): + """ Parse a meta.xml file with an event-driven parser and replace elements. + It would probably be a cleaner approach to use a DOM based parser and + then manipulate in memory. + Small issue: Reorders elements + """ + + def __init__(self, deletefields={}, yieldfields={}, addfields={}): + self.deletefields = deletefields + self.yieldfields = yieldfields + self.addfields = addfields + self._mimetype = '' + self.output = MetaCollector() + self._data = [] + self.seenfields = {} + xml.sax.saxutils.XMLGenerator.__init__(self, self.output, 'utf-8') + + def startElementNS(self, name, qname, attrs): + self._data = [] + field = name +# I can't modify the template until the tool replaces elements at the same +# location and not at the end +# if name == (METANS,u'template'): +# self._data = [attrs.get((XLINKNS,u'title'),'')] + if name == (METANS,u'user-defined'): + field = attrs.get((METANS,u'name')) + if field in self.deletefields: + self.output.dowrite = False + elif field in self.yieldfields: + del self.addfields[field] + xml.sax.saxutils.XMLGenerator.startElementNS(self, name, qname, attrs) + else: + xml.sax.saxutils.XMLGenerator.startElementNS(self, name, qname, attrs) + self._tag = field + + def endElementNS(self, name, qname): + field = name + if name == (METANS,u'user-defined'): + field = self._tag + if name == (OFFICENS,u'meta'): + for k,v in self.addfields.items(): + if len(v) > 0: + if type(k) == type(''): + xml.sax.saxutils.XMLGenerator.startElementNS(self,(METANS,u'user-defined'),None,{(METANS,u'name'):k}) + xml.sax.saxutils.XMLGenerator.characters(self, v) + xml.sax.saxutils.XMLGenerator.endElementNS(self, (METANS,u'user-defined'),None) + else: + xml.sax.saxutils.XMLGenerator.startElementNS(self, k, None, {}) + xml.sax.saxutils.XMLGenerator.characters(self, v) + xml.sax.saxutils.XMLGenerator.endElementNS(self, k, None) + if isinstance(self._tag, tuple): + texttag = self._tag[1] + else: + texttag = self._tag + self.seenfields[texttag] = self.data() + + if field in self.deletefields: + self.output.dowrite = True + else: + xml.sax.saxutils.XMLGenerator.endElementNS(self, name, qname) + + def characters(self, content): + xml.sax.saxutils.XMLGenerator.characters(self, content) + self._data.append(content) + + def meta(self): + return self.output.content() + + def data(self): + return normalize(''.join(self._data)) + +def get_metadata(stream): + zin = zipfile.ZipFile(stream, 'r') + odfs = odfmetaparser() + parser = xml.sax.make_parser() + parser.setFeature(xml.sax.handler.feature_namespaces, 1) + parser.setContentHandler(odfs) + content = zin.read('meta.xml') + parser.parse(StringIO(content)) + data = odfs.seenfields + mi = MetaInformation(None, []) + if data.has_key('title'): + mi.title = data['title'] + if data.has_key('creator'): + mi.authors = string_to_authors(data['creator']) + if data.has_key('description'): + mi.comments = data['description'] + if data.has_key('language'): + mi.language = data['language'] + if data.get('keywords', ''): + mi.tags = data['keywords'].split(',') + + return mi + +def main(args=sys.argv): + if len(args) != 2: + print 'Usage: %s file.odt'%args[0] + return 1 + mi = get_metadata(open(args[1], 'rb')) + print mi + return 0 + +if __name__ == '__main__': + sys.exit(main()) + +#now = time.localtime()[:6] +#outputfile = "-" +#writemeta = False # Do we change any meta data? +#usenormalize = False +# +#try: +# opts, args = getopt.getopt(sys.argv[1:], "cdlI:A:a:o:x:X:") +#except getopt.GetoptError: +# exitwithusage() +# +#if len(opts) == 0: +# opts = [ ('-l','') ] +# +#for o, a in opts: +# if o in ('-a','-A','-I'): +# writemeta = True +# if a.find(":") >= 0: +# k,v = a.split(":",1) +# else: +# k,v = (a, "") +# if len(k) == 0: +# exitwithusage() +# k = fields.get(k,k) +# addfields[k] = unicode(v,'utf-8') +# if o == '-a': +# yieldfields[k] = True +# if o == '-I': +# deletefields[k] = True +# if o == '-d': +# writemeta = True +# addfields[(DCNS,u'date')] = "%04d-%02d-%02dT%02d:%02d:%02d" % now +# deletefields[(DCNS,u'date')] = True +# if o == '-c': +# usenormalize = True +# if o == '-l': +# Xfields = fields.values() +# if o == "-x": +# xfields.append(fields.get(a,a)) +# if o == "-X": +# Xfields.append(fields.get(a,a)) +# if o == "-o": +# outputfile = a +# +## The specification says we should change the element to our own, +## and must not export the original identifier. +#if writemeta: +# addfields[(METANS,u'generator')] = TOOLSVERSION +# deletefields[(METANS,u'generator')] = True +# +#odfs = odfmetaparser() +#parser = xml.sax.make_parser() +#parser.setFeature(xml.sax.handler.feature_namespaces, 1) +#parser.setContentHandler(odfs) +# +#if len(args) == 0: +# zin = zipfile.ZipFile(sys.stdin,'r') +#else: +# if not zipfile.is_zipfile(args[0]): +# exitwithusage() +# zin = zipfile.ZipFile(args[0], 'r') +# +#content = zin.read('meta.xml') +#parser.parse(StringIO(content)) +# +#if writemeta: +# if outputfile == '-': +# if sys.stdout.isatty(): +# sys.stderr.write("Won't write ODF file to terminal\n") +# sys.exit(1) +# zout = zipfile.ZipFile(sys.stdout,"w") +# else: +# zout = zipfile.ZipFile(outputfile,"w") +# +# +# +# # Loop through the input zipfile and copy the content to the output until we +# # get to the meta.xml. Then substitute. +# for zinfo in zin.infolist(): +# if zinfo.filename == "meta.xml": +# # Write meta +# zi = zipfile.ZipInfo("meta.xml", now) +# zi.compress_type = zipfile.ZIP_DEFLATED +# zout.writestr(zi,odfs.meta() ) +# else: +# payload = zin.read(zinfo.filename) +# zout.writestr(zinfo, payload) +# +# zout.close() +#zin.close() diff --git a/src/calibre/ebooks/metadata/opf.py b/src/calibre/ebooks/metadata/opf.py index dcda78258a..69054571ec 100644 --- a/src/calibre/ebooks/metadata/opf.py +++ b/src/calibre/ebooks/metadata/opf.py @@ -7,7 +7,7 @@ import cStringIO import uuid from urllib import unquote, quote -from calibre import __appname__ +from calibre.constants import __appname__, __version__ from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, BeautifulSoup from calibre.ebooks.lrf import entity_to_unicode @@ -28,7 +28,10 @@ class ManifestItem(Resource): if item.has_key('href'): href = item['href'] if unquote(href) == href: - href = quote(href) + try: + href = quote(href) + except KeyError: + pass res = ManifestItem(href, basedir=basedir, is_path=False) mt = item.get('media-type', '').strip() if mt: @@ -241,7 +244,7 @@ class OPF(MetaInformation): def get_title(self): title = self.soup.package.metadata.find('dc:title') - if title: + if title and title.string: return self.ENTITY_PATTERN.sub(entity_to_unicode, title.string).strip() return self.default_title.strip() @@ -253,7 +256,7 @@ class OPF(MetaInformation): role = elem.get('opf:role') if not role: role = 'aut' - if role == 'aut': + if role == 'aut' and elem.string: raw = self.ENTITY_PATTERN.sub(entity_to_unicode, elem.string) au = raw.split(',') ans = [] @@ -293,13 +296,13 @@ class OPF(MetaInformation): def get_category(self): category = self.soup.find('dc:type') - if category: + if category and category.string: return self.ENTITY_PATTERN.sub(entity_to_unicode, category.string).strip() return None def get_publisher(self): publisher = self.soup.find('dc:publisher') - if publisher: + if publisher and publisher.string: return self.ENTITY_PATTERN.sub(entity_to_unicode, publisher.string).strip() return None @@ -308,7 +311,7 @@ class OPF(MetaInformation): scheme = item.get('scheme') if not scheme: scheme = item.get('opf:scheme') - if scheme is not None and scheme.lower() == 'isbn': + if scheme is not None and scheme.lower() == 'isbn' and item.string: return str(item.string).strip() return None @@ -320,7 +323,10 @@ class OPF(MetaInformation): def get_application_id(self): for item in self.soup.package.metadata.findAll('dc:identifier'): - if item.has_key('scheme') and item['scheme'] == __appname__: + scheme = item.get('scheme', None) + if scheme is None: + scheme = item.get('opf:scheme', None) + if scheme in ['libprs500', 'calibre']: return str(item.string).strip() return None @@ -353,7 +359,7 @@ class OPF(MetaInformation): def get_series_index(self): s = self.soup.package.metadata.find('series-index') - if s: + if s and s.string: try: return int(str(s.string).strip()) except: @@ -361,11 +367,8 @@ class OPF(MetaInformation): return None def get_rating(self): - xm = self.soup.package.metadata.find('x-metadata') - if not xm: - return None - s = xm.find('rating') - if s: + s = self.soup.package.metadata.find('rating') + if s and s.string: try: return int(str(s.string).strip()) except: @@ -483,7 +486,7 @@ class OPFCreator(MetaInformation): Set the toc. You must call :method:`create_spine` before calling this method. - `toc`: A :class:`TOC` object + :param toc: A :class:`TOC` object ''' self.toc = toc @@ -491,12 +494,21 @@ class OPFCreator(MetaInformation): 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): + def render(self, opf_stream, ncx_stream=None, ncx_manifest_entry=None): from calibre.resources import opf_template from calibre.utils.genshi.template import MarkupTemplate template = MarkupTemplate(opf_template) if self.manifest: self.manifest.set_basedir(self.base_path) + if ncx_manifest_entry is not None: + if not os.path.isabs(ncx_manifest_entry): + ncx_manifest_entry = os.path.join(self.base_path, ncx_manifest_entry) + remove = [i for i in self.manifest if i.id == 'ncx'] + for item in remove: + self.manifest.remove(item) + self.manifest.append(ManifestItem(ncx_manifest_entry, self.base_path)) + self.manifest[-1].id = 'ncx' + self.manifest[-1].mime_type = 'application/x-dtbncx+xml' if not self.guide: self.guide = Guide() if self.cover: @@ -506,7 +518,7 @@ class OPFCreator(MetaInformation): self.guide.set_cover(cover) self.guide.set_basedir(self.base_path) - opf = template.generate(__appname__=__appname__, mi=self).render('xml') + opf = template.generate(__appname__=__appname__, mi=self, __version__=__version__).render('xml') opf_stream.write(opf) opf_stream.flush() toc = getattr(self, 'toc', None) diff --git a/src/calibre/ebooks/metadata/opf.xml b/src/calibre/ebooks/metadata/opf.xml index 3a6cfec58c..6cb70c5b1e 100644 --- a/src/calibre/ebooks/metadata/opf.xml +++ b/src/calibre/ebooks/metadata/opf.xml @@ -8,6 +8,7 @@ ${mi.title} ${author} + ${'%s (%s)'%(__appname__, __version__)} [http://${__appname__}.kovidgoyal.net] ${mi.application_id} ${mi.language if mi.language else 'Unknown'} @@ -16,13 +17,19 @@ ${mi.publisher} ${mi.isbn} ${mi.series} - ${mi.series_index} + ${mi.series_index} ${mi.rating} ${tag} + + + + + + @@ -36,10 +43,5 @@ - - - - - diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py new file mode 100644 index 0000000000..3f0adaf662 --- /dev/null +++ b/src/calibre/ebooks/metadata/opf2.py @@ -0,0 +1,892 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +lxml based OPF parser. +''' + +import sys, unittest, functools, os, mimetypes, uuid, glob +from urllib import unquote +from urlparse import urlparse + +from lxml import etree + +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 + + +class Resource(object): + ''' + 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._href = None + self._basedir = basedir + self.path = None + self.fragment = '' + try: + self.mime_type = mimetypes.guess_type(href_or_path)[0] + except: + self.mime_type = None + if self.mime_type is None: + self.mime_type = 'application/octet-stream' + if is_path: + path = href_or_path + if not os.path.isabs(path): + path = os.path.abspath(os.path.join(basedir, path)) + if isinstance(path, str): + path = path.decode(sys.getfilesystemencoding()) + self.path = path + else: + href_or_path = href_or_path + url = urlparse(href_or_path) + if url[0] not in ('', 'file'): + self._href = href_or_path + else: + pc = url[2] + if isinstance(pc, unicode): + pc = pc.encode('utf-8') + 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. + ''' + if basedir is None: + if self._basedir: + basedir = self._basedir + else: + basedir = os.getcwd() + if self.path is None: + return self._href + f = self.fragment.encode('utf-8') if isinstance(self.fragment, unicode) else self.fragment + frag = '#'+f if self.fragment else '' + if self.path == basedir: + return ''+frag + try: + rpath = relpath(self.path, basedir) + except OSError: # On windows path and basedir could be on different drives + rpath = self.path + 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() + for spec in os.walk(top, topdown=topdown): + path = os.path.abspath(os.path.join(spec[0], spec[1])) + res = Resource.from_path(path) + 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) + if href: + res = ManifestItem(href, basedir=basedir, is_path=True) + mt = item.get('media-type', '').strip() + if mt: + res.mime_type = mt + return res + + @apply + def media_type(): + def fget(self): + return self.mime_type + 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() + if index == 1: + return self.media_type + raise IndexError('%d out of bounds.'%index) + + +class Manifest(ResourceCollection): + + @staticmethod + def from_opf_manifest_element(items, dir): + m = Manifest() + for item in items: + try: + m.append(ManifestItem.from_opf_manifest_item(item, dir)) + id = item.get('id', '') + if not id: + id = 'id%d'%m.next_id + m[-1].id = id + m.next_id += 1 + except ValueError: + continue + return m + + @staticmethod + def from_paths(entries): + ''' + `entries`: List of (path, mime-type) If mime-type is None it is autodetected + ''' + m = Manifest() + for path, mt in entries: + mi = ManifestItem(path, is_path=True) + if mt: + mi.mime_type = mt + mi.id = 'id%d'%m.next_id + 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: + mi.mime_type = mime_type + mi.id = 'id%d'%self.next_id + 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 + + 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) + for itemref in itemrefs: + idref = itemref.get('idref', None) + if idref is not None: + r = Spine.Item(s.manifest.id_for_path, + s.manifest.path_for_id(idref), is_path=True) + r.is_linear = itemref.get('linear', 'yes') == 'yes' + s.append(r) + return s + + @staticmethod + def from_paths(paths, manifest): + s = Spine(manifest) + for path in paths: + try: + s.append(Spine.Item(s.manifest.id_for_path, path, is_path=True)) + 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 + with the items identified by ids. ids can be a list of any length. + ''' + items = [] + for id in ids: + path = self.manifest.path_for_id(id) + if path is None: + 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: + yield r.path + + def nonlinear_items(self): + 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') + res = Guide.Reference(href, basedir, is_path=False) + res.title = title + res.type = type + return res + + def __repr__(self): + ans = '' + + + @staticmethod + def from_opf_guide(references, base_dir=os.getcwdu()): + coll = Guide() + for ref in references: + try: + ref = Guide.Reference.from_opf_resource_item(ref, base_dir) + coll.append(ref) + 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'): + self.append(Guide.Reference(path, is_path=True)) + self[-1].type = type + self[-1].title = '' + + +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: + return None + ans = obj.get_text(ans) + if ans is None: + return ans + if self.formatter is not None: + try: + ans = self.formatter(ans) + 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: + elem = obj.create_metadata_element(self.name, ns='dc' if self.is_dc else 'opf') + elem.text = unicode(val) + +class OPF(object): + MIMETYPE = 'application/oebps-package+xml' + PARSER = etree.XMLParser(recover=True) + NAMESPACES = { + None : "http://www.idpf.org/2007/opf", + 'dc' : "http://purl.org/dc/elements/1.1/", + 'opf' : "http://www.idpf.org/2007/opf", + } + xpn = NAMESPACES.copy() + xpn.pop(None) + xpn['re'] = 'http://exslt.org/regular-expressions' + XPath = functools.partial(etree.XPath, namespaces=xpn) + TEXT = XPath('string()') + + + metadata_path = XPath('descendant::*[re:match(name(), "metadata", "i")]') + metadata_elem_path = XPath('descendant::*[re:match(name(), $name, "i")]') + series_path = XPath('descendant::*[re:match(name(), "series$", "i")]') + authors_path = XPath('descendant::*[re:match(name(), "creator", "i") and (@role="aut" or @opf:role="aut")]') + 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")]') + isbn_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+ + '(re:match(@scheme, "isbn", "i") or re:match(@opf:scheme, "isbn", "i"))]') + manifest_path = XPath('descendant::*[re:match(name(), "manifest", "i")]/*[re:match(name(), "item", "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') + comments = MetadataField('description') + category = MetadataField('category') + 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()): + if not hasattr(stream, 'read'): + stream = open(stream, 'rb') + self.basedir = self.base_dir = basedir + raw, self.encoding = xml_to_unicode(stream.read(), strip_encoding_pats=True, resolve_entities=True) + + self.root = etree.fromstring(raw, self.PARSER) + self.metadata = self.metadata_path(self.root) + if not self.metadata: + raise ValueError('Malformed OPF file: No element') + self.metadata = self.metadata[0] + self.unquote_urls() + self.manifest = Manifest() + m = self.manifest_path(self.root) + if m: + self.manifest = Manifest.from_opf_manifest_element(m, basedir) + self.spine = None + s = self.spine_path(self.root) + if s: + self.spine = Spine.from_opf_spine_element(s, self.manifest) + self.guide = None + guide = self.guide_path(self.root) + 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: + spine = self.XPath('descendant::*[re:match(name(), "spine", "i")]')(self.root) + toc = None + if spine: + spine = spine[0] + toc = spine.get('toc', None) + if toc is None and self.guide: + for item in self.guide: + if item.type and item.type.lower() == 'toc': + toc = item.path + if toc is None: + 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'): + path = self.manifest.path_for_id(toc) + if path: + self.toc.read_ncx_toc(path) + else: + f = glob.glob(os.path.join(self.base_dir, '*.ncx')) + if f: + self.toc.read_ncx_toc(f[0]) + else: + self.toc.read_html_toc(toc) + except: + pass + + + + def get_text(self, elem): + return u''.join(self.TEXT(elem)) + + 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 + for c in xrange(1, sys.maxint): + id = 'id%d'%c + if id not in ids: + break + if not media_type: + media_type = 'application/xhtml+xml' + 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): + item2.set('id', item.get('id')+'.%d'%(i+1)) + manifest = item.getparent() + index = manifest.index(item) + manifest[index:index+1] = items + return [i.get('id') for i in items] + + def iterspine(self): + return self.spine_path(self.root) + + 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] + old = [i for i in self.iterspine() if i.get('idref', None) == idref] + 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'], + 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', '')) + if not isinstance(raw, unicode): + raw = raw.decode('utf-8') + return raw + for item in self.itermanifest(): + 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: + self.metadata.remove(elem) + for author in val: + elem = self.create_metadata_element('creator', ns='dc', + attrib={'{%s}role'%self.NAMESPACES['opf']:'aut'}) + elem.text = author + + return property(fget=fget, fset=fset) + + @apply + def author_sort(): + + def fget(self): + matches = self.authors_path(self.metadata) + if matches: + ans = matches[0].get('opf:file-as', None) + return ans if ans else matches[0].get('file-as', None) + + def fset(self, val): + matches = self.authors_path(self.metadata) + if matches: + 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', ns='dc') + elem.text = unicode(tag) + + return property(fget=fget, fset=fset) + + @apply + def isbn(): + + def fget(self): + for match in self.isbn_path(self.metadata): + return match.text if match.text else None + + def fset(self, val): + matches = self.isbn_path(self.metadata) + if not matches: + matches = [self.create_metadata_element('identifier', ns='dc', + attrib={'{%s}scheme'%self.NAMESPACES['opf']:'ISBN'})] + matches[0].text = unicode(val) + + return property(fget=fget, fset=fset) + + @apply + def series(): + + def fget(self): + for match in self.series_path(self.metadata): + return match.text if match.text else None + + def fset(self, val): + matches = self.series_path(self.metadata) + if not matches: + matches = [self.create_metadata_element('series')] + matches[0].text = unicode(val) + + return property(fget=fget, fset=fset) + + + + @apply + def book_producer(): + + def fget(self): + for match in self.bkp_path(self.metadata): + return match.text if match.text else None + + def fset(self, val): + matches = self.bkp_path(self.metadata) + if not matches: + matches = [self.create_metadata_element('contributor', ns='dc', + attrib={'{%s}role'%self.NAMESPACES['opf']:'bkp'})] + matches[0].text = unicode(val) + return property(fget=fget, fset=fset) + + + @apply + def cover(): + + def fget(self): + if self.guide is not None: + for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): + for item in self.guide: + if item.type.lower() == t: + return item.path + + 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, + attrib={'type':'cover', 'href':self.guide[-1].href()}) + id = self.manifest.id_for_path(self.cover) + if id is None: + for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): + 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) + + 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, ns='opf'): + elem = etree.SubElement(self.metadata, '{%s}%s'%(self.NAMESPACES[ns], name), + attrib=attrib, 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) + + def smart_update(self, mi): + for attr in ('author_sort', 'title_sort', 'comments', 'category', + 'publisher', 'series', 'series_index', 'rating', + 'isbn', 'language', 'tags', 'title', 'authors'): + 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. + @param base_path: An absolute path to the directory in which this OPF file + will eventually be. This is used by the L{create_manifest} method + to convert paths to files into relative paths. + ''' + MetaInformation.__init__(self, *args, **kwargs) + self.base_path = os.path.abspath(base_path) + if self.application_id is None: + self.application_id = str(uuid.uuid4()) + if not isinstance(self.toc, TOC): + self.toc = None + if not self.authors: + self.authors = [_('Unknown')] + if self.guide is None: + 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 + (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)) + + for i in files_and_dirs: + if os.path.isdir(i): + dodir(i) + else: + entries.append((i, None)) + + 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 + 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): + from calibre.resources import opf_template + from calibre.utils.genshi.template import MarkupTemplate + template = MarkupTemplate(opf_template) + if self.manifest: + self.manifest.set_basedir(self.base_path) + if ncx_manifest_entry is not None: + if not os.path.isabs(ncx_manifest_entry): + ncx_manifest_entry = os.path.join(self.base_path, ncx_manifest_entry) + remove = [i for i in self.manifest if i.id == 'ncx'] + for item in remove: + self.manifest.remove(item) + self.manifest.append(ManifestItem(ncx_manifest_entry, self.base_path)) + self.manifest[-1].id = 'ncx' + self.manifest[-1].mime_type = 'application/x-dtbncx+xml' + if not self.guide: + self.guide = Guide() + if self.cover: + cover = self.cover + if not os.path.isabs(cover): + cover = os.path.abspath(os.path.join(self.base_path, cover)) + self.guide.set_cover(cover) + self.guide.set_basedir(self.base_path) + opf = template.generate(__appname__=__appname__, mi=self, __version__=__version__).render('xml') + opf_stream.write(opf) + opf_stream.flush() + toc = getattr(self, 'toc', None) + if toc is not None and ncx_stream is not None: + toc.render(ncx_stream, self.application_id) + ncx_stream.flush() + + +class OPFTest(unittest.TestCase): + + def setUp(self): + import cStringIO + self.stream = cStringIO.StringIO( +'''\ + + + + A Cool & © ß Title + Monkey Kitchen, Next + OneTwo + 123456789 + + A one book series + + + + + + +''' + ) + self.opf = OPF(self.stream, os.getcwd()) + + def testReading(self): + 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.tags, ['One', 'Two']) + self.assertEqual(opf.isbn, '123456789') + self.assertEqual(opf.series, 'A one book series') + self.assertEqual(opf.series_index, None) + 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)]: + setattr(self.opf, *test) + self.assertEqual(getattr(self.opf, test[0]), test[1]) + + self.opf.render() + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(OPFTest) + +def test(): + unittest.TextTestRunner(verbosity=2).run(suite()) + +if __name__ == '__main__': + sys.exit(test()) \ No newline at end of file diff --git a/src/calibre/ebooks/metadata/pdf.py b/src/calibre/ebooks/metadata/pdf.py index bf8d50adf4..84a38d9ee4 100644 --- a/src/calibre/ebooks/metadata/pdf.py +++ b/src/calibre/ebooks/metadata/pdf.py @@ -5,12 +5,11 @@ __copyright__ = '2008, Kovid Goyal ' import sys, os from calibre.ebooks.metadata import MetaInformation -from calibre.ebooks.pyPdf import PdfFileReader +from pyPdf import PdfFileReader def get_metadata(stream): """ Return metadata as a L{MetaInfo} object """ - title = 'Unknown' - mi = MetaInformation(title, ['Unknown']) + mi = MetaInformation(_('Unknown'), [_('Unknown')]) stream.seek(0) try: info = PdfFileReader(stream).getDocumentInfo() diff --git a/src/calibre/ebooks/metadata/rb.py b/src/calibre/ebooks/metadata/rb.py new file mode 100644 index 0000000000..6af75c9efd --- /dev/null +++ b/src/calibre/ebooks/metadata/rb.py @@ -0,0 +1,68 @@ +__license__ = 'GPL v3' +__copyright__ = '2008, Ashish Kulkarni ' +'''Read meta information from RB files''' + +import sys, os, struct + +from calibre.ebooks.metadata import MetaInformation + +MAGIC = '\xb0\x0c\xb0\x0c\x02\x00NUVO\x00\x00\x00\x00' + +def get_metadata(stream): + """ Return metadata as a L{MetaInfo} object """ + title = 'Unknown' + mi = MetaInformation(title, ['Unknown']) + stream.seek(0) + try: + if not stream.read(14) == MAGIC: + print >>sys.stderr, u'Couldn\'t read RB header from file' + return mi + stream.read(10) + + read_i32 = lambda: struct.unpack('>sys.stderr, u'Couldn\'t find INFO from RB file' + return mi + + stream.seek(offset) + info = stream.read(length).splitlines() + for line in info: + if not '=' in line: + continue + key, value = line.split('=') + if key.strip() == 'TITLE': + mi.title = value.strip() + elif key.strip() == 'AUTHOR': + src = value.split('&') + authors = [] + for au in src: + authors += au.split(',') + mi.authors = authors + mi.author = value + except Exception, err: + msg = u'Couldn\'t read metadata from rb: %s with error %s'%(mi.title, unicode(err)) + print >>sys.stderr, msg.encode('utf8') + raise + return mi + + +def main(args=sys.argv): + if len(args) != 2: + print >>sys.stderr, _('Usage: rb-meta file.rb') + print >>sys.stderr, _('No filename specified.') + return 1 + + path = os.path.abspath(os.path.expanduser(args[1])) + print get_metadata(open(path, 'rb')) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/metadata/toc.py b/src/calibre/ebooks/metadata/toc.py index 5cecda1c6d..f50a525264 100644 --- a/src/calibre/ebooks/metadata/toc.py +++ b/src/calibre/ebooks/metadata/toc.py @@ -1,7 +1,7 @@ #!/usr/bin/env python __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import os, glob, sys +import os, glob from urlparse import urlparse from urllib import unquote @@ -21,18 +21,41 @@ class NCXSoup(BeautifulStoneSoup): class TOC(list): def __init__(self, href=None, fragment=None, text=None, parent=None, play_order=0, - base_path=os.getcwd()): + base_path=os.getcwd(), type='unknown'): self.href = href self.fragment = fragment + if not self.fragment: + self.fragment = None self.text = text self.parent = parent self.base_path = base_path self.play_order = play_order + self.type = type - def add_item(self, href, fragment, text): - play_order = (self[-1].play_order if len(self) else self.play_order) + 1 + def count(self, type): + return len([i for i in self.flat() if i.type == type]) + + def purge(self, types, max=0): + remove = [] + for entry in self.flat(): + if entry.type in types: + remove.append(entry) + remove = remove[max:] + for entry in remove: + if entry.parent is None: + continue + entry.parent.remove(entry) + return remove + + def remove(self, entry): + list.remove(self, entry) + entry.parent = None + + def add_item(self, href, fragment, text, play_order=None, type='unknown'): + if play_order is None: + play_order = (self[-1].play_order if len(self) else self.play_order) + 1 self.append(TOC(href=href, fragment=fragment, text=text, parent=self, - base_path=self.base_path, play_order=play_order)) + base_path=self.base_path, play_order=play_order, type=type)) return self[-1] def top_level_items(self): @@ -48,14 +71,24 @@ class TOC(list): depth = c + 1 return depth + def flat(self): + 'Depth first iteration over the tree rooted at self' + yield self + for obj in self: + for i in obj.flat(): + yield i + @apply def abspath(): doc='Return the file this toc entry points to as a absolute path to a file on the system.' def fget(self): + if self.href is None: + return None path = self.href.replace('/', os.sep) if not os.path.isabs(path): path = os.path.join(self.base_path, path) return path + return property(fget=fget, doc=doc) def read_from_opf(self, opfreader): @@ -85,15 +118,15 @@ class TOC(list): self.read_html_toc(toc) except: - print 'WARNING: Could not read Table of Contents:' - import traceback - traceback.print_exc(file=sys.stdout) - print 'Continuing anyway' + print 'WARNING: Could not read Table of Contents. Continuing anyway.' else: path = opfreader.manifest.item(toc.lower()) path = getattr(path, 'path', path) if path and os.access(path, os.R_OK): - self.read_ncx_toc(path) + try: + self.read_ncx_toc(path) + except Exception, err: + print 'WARNING: Invalid NCX file:', err return cwd = os.path.abspath(self.base_path) m = glob.glob(os.path.join(cwd, '*.ncx')) @@ -106,14 +139,16 @@ class TOC(list): soup = NCXSoup(xml_to_unicode(open(toc, 'rb').read())[0]) def process_navpoint(np, dest): - play_order = np.get('playOrder', 1) + play_order = np.get('playOrder', None) + if play_order is None: + play_order = int(np.get('playorder', 1)) href = fragment = text = None nl = np.find('navlabel') if nl is not None: text = u'' for txt in nl.findAll('text'): text += ''.join([unicode(s) for s in txt.findAll(text=True)]) - content = elem.find('content') + content = np.find('content') if content is None or not content.has_key('src') or not txt: return @@ -143,8 +178,20 @@ class TOC(list): continue purl = urlparse(unquote(a['href'])) href, fragment = purl[2], purl[5] + if not fragment: + fragment = None + else: + fragment = fragment.strip() + href = href.strip() + txt = ''.join([unicode(s).strip() for s in a.findAll(text=True)]) - self.add_item(href, fragment, txt) + add = True + for i in self.flat(): + if i.href == href and i.fragment == fragment: + add = False + break + if add: + self.add_item(href, fragment, txt) def render(self, stream, uid): from calibre.resources import ncx_template diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index fccb4f68b4..15324dfbbc 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -12,7 +12,8 @@ try: except ImportError: import Image as PILImage -from calibre import __appname__ +from calibre import __appname__, entity_to_unicode +from calibre.ebooks import DRMError from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag from calibre.ebooks.mobi import MobiError from calibre.ebooks.mobi.huffcdic import HuffReader @@ -160,12 +161,12 @@ class MobiReader(object): self.book_header = BookHeader(self.sections[0][0], self.ident) - + self.name = self.name.decode(self.book_header.codec, 'replace') def extract_content(self, output_dir=os.getcwdu()): output_dir = os.path.abspath(output_dir) if self.book_header.encryption_type != 0: - raise MobiError('Cannot extract content from a DRM protected ebook') + raise DRMError(self.name) processed_records = self.extract_text() self.add_anchors() @@ -176,15 +177,17 @@ class MobiReader(object): self.processed_html = \ re.compile('', re.IGNORECASE).sub( - '\n' + '\n\n' '\n' '\n', self.processed_html) - soup = BeautifulSoup(self.processed_html.replace('> <', '>\n<')) + soup = BeautifulSoup(self.processed_html) self.cleanup_soup(soup) guide = soup.find('guide') for elem in soup.findAll(['metadata', 'guide']): @@ -210,6 +213,11 @@ 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('> <', '>\n<') + self.processed_html = self.processed_html.replace('', '') + self.processed_html = self.processed_html.replace('', '') + self.processed_html = self.processed_html.replace('', '') + self.processed_html = self.processed_html.replace('', '') def cleanup_soup(self, soup): for tag in soup.recursiveChildGenerator(): @@ -256,17 +264,19 @@ class MobiReader(object): if ref.type.lower() == 'toc': toc = ref.href() if toc: - index = self.processed_html.find(' -1: raw = ''+self.processed_html[index:] soup = BeautifulSoup(raw) tocobj = TOC() for a in soup.findAll('a', href=True): try: - text = ''.join(a.findAll(text=True)).strip() + text = u''.join(a.findAll(text=True)).strip() except: text = '' + text = ent_pat.sub(entity_to_unicode, text) tocobj.add_item(toc.partition('#')[0], a['href'][1:], text) if tocobj is not None: opf.set_toc(tocobj) @@ -341,12 +351,14 @@ class MobiReader(object): pos = 0 self.processed_html = '' for end in 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 + self.processed_html += self.mobi_html[pos:end] + ''%(oend, oend) pos = end self.processed_html += self.mobi_html[pos:] diff --git a/src/calibre/ebooks/odt/__init__.py b/src/calibre/ebooks/odt/__init__.py new file mode 100644 index 0000000000..d5fc74348c --- /dev/null +++ b/src/calibre/ebooks/odt/__init__.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Handle the Open Document Format +''' + diff --git a/src/calibre/ebooks/odt/to_oeb.py b/src/calibre/ebooks/odt/to_oeb.py new file mode 100644 index 0000000000..7cb354884e --- /dev/null +++ b/src/calibre/ebooks/odt/to_oeb.py @@ -0,0 +1,72 @@ +from __future__ import with_statement +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Convert an ODT file into a Open Ebook +''' +import os, sys +from odf.odf2xhtml import ODF2XHTML + +from calibre import CurrentDir, walk +from calibre.utils.zipfile import ZipFile +from calibre.utils.config import OptionParser +from calibre.ebooks.metadata.odt import get_metadata +from calibre.ebooks.metadata.opf2 import OPFCreator + +class Extract(ODF2XHTML): + + def extract_pictures(self, zf): + if not os.path.exists('Pictures'): + os.makedirs('Pictures') + for name in zf.namelist(): + if name.startswith('Pictures'): + data = zf.read(name) + with open(name, 'wb') as f: + f.write(data) + + def __call__(self, path, odir): + if not os.path.exists(odir): + os.makedirs(odir) + path = os.path.abspath(path) + with CurrentDir(odir): + print 'Extracting ODT file...' + html = self.odf2xhtml(path) + with open('index.html', 'wb') as f: + f.write(html.encode('utf-8')) + with open(path, 'rb') as f: + zf = ZipFile(f, 'r') + self.extract_pictures(zf) + f.seek(0) + mi = get_metadata(f) + if not mi.title: + mi.title = os.path.splitext(os.path.basename(path)) + if not mi.authors: + mi.authors = [_('Unknown')] + opf = OPFCreator(os.path.abspath(os.getcwdu()), mi) + opf.create_manifest([(os.path.abspath(f), None) for f in walk(os.getcwd())]) + opf.create_spine([os.path.abspath('index.html')]) + with open('metadata.opf', 'wb') as f: + opf.render(f) + return os.path.abspath('metadata.opf') + +def option_parser(): + parser = OptionParser('%prog [options] file.odt') + parser.add_option('-o', '--output-dir', default='.', + help=_('The output directory. Defaults to the current directory.')) + return parser + +def main(args=sys.argv): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) < 2: + parser.print_help() + print 'No ODT file specified' + return 1 + Extract()(args[1], os.path.abspath(opts.output_dir)) + print 'Extracted to', os.path.abspath(opts.output_dir) + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index df2596564b..c976c3428f 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -3,7 +3,8 @@ __copyright__ = '2008, Kovid Goyal ' """ The GUI """ import sys, os, re, StringIO, traceback from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \ - QByteArray, QLocale, QUrl, QTranslator, QCoreApplication + QByteArray, QLocale, QUrl, QTranslator, QCoreApplication, \ + QModelIndex from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \ QIcon, QTableView, QDialogButtonBox, QApplication @@ -20,8 +21,8 @@ def _config(): c = Config('gui', 'preferences for the calibre GUI') c.add_opt('frequently_used_directories', default=[], help=_('Frequently used directories')) - c.add_opt('send_to_device_by_default', default=True, - help=_('Send downloaded periodical content to device automatically')) + c.add_opt('send_to_storage_card_by_default', default=False, + help=_('Send file to storage card instead of main memory by default')) c.add_opt('save_to_disk_single_format', default='lrf', help=_('The format to use when saving single files to disk')) c.add_opt('confirm_delete', default=False, @@ -36,6 +37,8 @@ def _config(): help=_('Notify when a new version is available')) c.add_opt('use_roman_numerals_for_series_number', default=True, help=_('Use Roman numerals for series number')) + c.add_opt('sort_by_popularity', default=False, + help=_('Sort tags list by popularity')) c.add_opt('cover_flow_queue_length', default=6, help=_('Number of covers to show in the cover browsing mode')) c.add_opt('LRF_conversion_defaults', default=[], @@ -159,7 +162,7 @@ class TableView(QTableView): else: cols = dynamic[key] if not cols: - cols = [True for i in range(self.model().columnCount(self))] + cols = [True for i in range(self.model().columnCount(QModelIndex()))] for i in range(len(cols)): hidden = self.isColumnHidden(i) @@ -195,6 +198,7 @@ class FileIconProvider(QFileIconProvider): 'prc' : 'mobi', 'azw' : 'mobi', 'mobi' : 'mobi', + 'epub' : 'epub', } def __init__(self): @@ -221,7 +225,7 @@ class FileIconProvider(QFileIconProvider): return icon def icon_from_ext(self, ext): - key = self.key_from_ext(ext) + key = self.key_from_ext(ext.lower() if ext else '') return self.cached_icon(key) def load_icon(self, fileinfo): @@ -303,7 +307,7 @@ class FileDialog(QObject): QObject.connect(self.fd, SIGNAL('accepted()'), self.save_dir) self.accepted = self.fd.exec_() == QFileDialog.Accepted else: - dir = dynamic.get(self.dialog_name, default=os.path.expanduser('~')) + dir = dynamic.get(self.dialog_name, os.path.expanduser('~')) self.selected_files = [] if mode == QFileDialog.AnyFile: f = qstring_to_unicode( diff --git a/src/calibre/gui2/dialogs/book_info.py b/src/calibre/gui2/dialogs/book_info.py index b27c9b4ab4..72b305fd78 100644 --- a/src/calibre/gui2/dialogs/book_info.py +++ b/src/calibre/gui2/dialogs/book_info.py @@ -5,24 +5,68 @@ __docformat__ = 'restructuredtext en' ''' ''' -import textwrap +import textwrap, os -from PyQt4.QtCore import QCoreApplication -from PyQt4.QtGui import QDialog, QPixmap, QGraphicsScene, QIcon +from PyQt4.QtCore import QCoreApplication, SIGNAL, QModelIndex, QUrl +from PyQt4.QtGui import QDialog, QPixmap, QGraphicsScene, QIcon, QDesktopServices from calibre.gui2.dialogs.book_info_ui import Ui_BookInfo class BookInfo(QDialog, Ui_BookInfo): - def __init__(self, parent, info): + def __init__(self, parent, view, row): QDialog.__init__(self, parent) Ui_BookInfo.__init__(self) self.setupUi(self) - - self.setWindowTitle(info[_('Title')]) desktop = QCoreApplication.instance().desktop() screen_height = desktop.availableGeometry().height() - 100 self.resize(self.size().width(), screen_height) + + + self.view = view + self.current_row = None + self.refresh(row) + self.connect(self.view.selectionModel(), SIGNAL('currentChanged(QModelIndex,QModelIndex)'), self.slave) + self.connect(self.next_button, SIGNAL('clicked()'), self.next) + self.connect(self.previous_button, SIGNAL('clicked()'), self.previous) + self.connect(self.text, SIGNAL('linkActivated(QString)'), self.open_book_path) + + def slave(self, current, previous): + row = current.row() + self.refresh(row) + + def open_book_path(self, path): + if os.sep in unicode(path): + QDesktopServices.openUrl(QUrl('file:'+path)) + else: + format = unicode(path) + path = self.view.model().db.format_abspath(self.current_row, format) + if path is not None: + QDesktopServices.openUrl(QUrl('file:'+path)) + + + def next(self): + row = self.view.currentIndex().row() + ni = self.view.model().index(row+1, 0) + if ni.isValid(): + self.view.setCurrentIndex(ni) + + def previous(self): + row = self.view.currentIndex().row() + ni = self.view.model().index(row-1, 0) + if ni.isValid(): + self.view.setCurrentIndex(ni) + + def refresh(self, row): + if isinstance(row, QModelIndex): + row = row.row() + if row == self.current_row: + return + self.previous_button.setEnabled(False if row == 0 else True) + self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True) + self.current_row = row + info = self.view.model().get_book_info(row) + self.setWindowTitle(info[_('Title')]) self.title.setText(''+info.pop(_('Title'))) self.comments.setText(info.pop(_('Comments'), '')) @@ -37,6 +81,15 @@ class BookInfo(QDialog, Ui_BookInfo): rows = u'' self.text.setText('') self.data = info + if _('Path') in info.keys(): + p = info[_('Path')] + info[_('Path')] = '%s'%(p, p) + if _('Formats') in info.keys(): + formats = info[_('Formats')].split(',') + info[_('Formats')] = '' + for f in formats: + f = f.strip() + info[_('Formats')] += '%s, '%(f,f) for key in info.keys(): txt = info[key] txt = u'
\n'.join(textwrap.wrap(txt, 120)) diff --git a/src/calibre/gui2/dialogs/book_info.ui b/src/calibre/gui2/dialogs/book_info.ui index d79dbfe5c7..28b27b99b4 100644 --- a/src/calibre/gui2/dialogs/book_info.ui +++ b/src/calibre/gui2/dialogs/book_info.ui @@ -6,14 +6,14 @@ 0 0 917 - 780 + 783 Dialog - - + + TextLabel @@ -23,51 +23,68 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - - + + + + + + + + + TextLabel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Comments + + + + + + + + + + - + - TextLabel + &Previous - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true + + + :/images/previous.svg:/images/previous.svg - - - Comments + + + &Next + + + + :/images/next.svg:/images/next.svg - - - - - - - + + - + + + diff --git a/src/calibre/gui2/dialogs/comicconf.py b/src/calibre/gui2/dialogs/comicconf.py index 32bd1547be..50f4254be2 100644 --- a/src/calibre/gui2/dialogs/comicconf.py +++ b/src/calibre/gui2/dialogs/comicconf.py @@ -57,6 +57,8 @@ class ComicConf(QDialog, Ui_Dialog): self.opt_dont_sharpen.setChecked(opts.dont_sharpen) self.opt_landscape.setChecked(opts.landscape) self.opt_no_sort.setChecked(opts.no_sort) + self.opt_despeckle.setChecked(opts.despeckle) + self.opt_wide.setChecked(opts.wide) self.opt_right2left.setChecked(opts.right2left) for opt in self.config.option_set.preferences: @@ -79,4 +81,4 @@ class ComicConf(QDialog, Ui_Dialog): else: raise Exception('Bad coding') self.config.set(opt.name, val) - return QDialog.accept(self) \ No newline at end of file + return QDialog.accept(self) diff --git a/src/calibre/gui2/dialogs/comicconf.ui b/src/calibre/gui2/dialogs/comicconf.ui index 07df7dc8a8..36af85764a 100644 --- a/src/calibre/gui2/dialogs/comicconf.ui +++ b/src/calibre/gui2/dialogs/comicconf.ui @@ -100,21 +100,21 @@
- + &Landscape - + Don't so&rt - + Qt::Horizontal @@ -124,13 +124,27 @@ - + &Right to left + + + + De&speckle + + + + + + + &Wide + + + diff --git a/src/calibre/gui2/dialogs/config.py b/src/calibre/gui2/dialogs/config.py index b0cddc6a71..2f704e91fa 100644 --- a/src/calibre/gui2/dialogs/config.py +++ b/src/calibre/gui2/dialogs/config.py @@ -7,7 +7,7 @@ from PyQt4.QtCore import SIGNAL, QTimer, Qt, QSize, QVariant from calibre import islinux from calibre.gui2.dialogs.config_ui import Ui_Dialog -from calibre.gui2 import qstring_to_unicode, choose_dir, error_dialog, config +from calibre.gui2 import qstring_to_unicode, choose_dir, error_dialog, config, warning_dialog from calibre.utils.config import prefs from calibre.gui2.widgets import FilenamePattern from calibre.ebooks import BOOK_EXTENSIONS @@ -20,8 +20,9 @@ class ConfigDialog(QDialog, Ui_Dialog): Ui_Dialog.__init__(self) self.ICON_SIZES = {0:QSize(48, 48), 1:QSize(32,32), 2:QSize(24,24)} self.setupUi(self) - self.item1 = QListWidgetItem(QIcon(':/images/metadata.svg'), _('Basic'), self.category_list) - self.item2 = QListWidgetItem(QIcon(':/images/view.svg'), _('Advanced'), self.category_list) + self.item1 = QListWidgetItem(QIcon(':/images/metadata.svg'), _('General'), self.category_list) + self.item2 = QListWidgetItem(QIcon(':/images/lookfeel.svg'), _('Interface'), self.category_list) + self.item3 = QListWidgetItem(QIcon(':/images/view.svg'), _('Advanced'), self.category_list) self.db = db self.current_cols = columns path = prefs['library_path'] @@ -66,6 +67,23 @@ class ConfigDialog(QDialog, Ui_Dialog): self.single_format.setCurrentIndex(BOOK_EXTENSIONS.index(single_format)) self.cover_browse.setValue(config['cover_flow_queue_length']) self.confirm_delete.setChecked(config['confirm_delete']) + from calibre.translations.compiled import translations + from calibre.translations import language_codes + from calibre.startup import get_lang + lang = get_lang() + if lang is not None and language_codes.has_key(lang): + self.language.addItem(language_codes[lang], QVariant(lang)) + items = [(l, language_codes[l]) for l in translations.keys() if l != lang] + if lang != 'en': + items.append(('en', 'English')) + items.sort(cmp=lambda x, y: cmp(x[1], y[1])) + for item in items: + self.language.addItem(item[1], QVariant(item[0])) + + self.output_format.setCurrentIndex(0 if prefs['output_format'] == 'LRF' else 1) + self.pdf_metadata.setChecked(prefs['read_file_metadata']) + + def compact(self, toggled): d = Vacuum(self, self.db) @@ -97,8 +115,15 @@ class ConfigDialog(QDialog, Ui_Dialog): config['confirm_delete'] = bool(self.confirm_delete.isChecked()) pattern = self.filename_pattern.commit() prefs['filename_pattern'] = pattern + prefs['read_file_metadata'] = bool(self.pdf_metadata.isChecked()) config['save_to_disk_single_format'] = BOOK_EXTENSIONS[self.single_format.currentIndex()] config['cover_flow_queue_length'] = self.cover_browse.value() + prefs['language'] = str(self.language.itemData(self.language.currentIndex()).toString()) + of = str(self.output_format.currentText()) + if of != prefs['output_format'] and 'epub' in of.lower(): + warning_dialog(self, 'Warning', + '

EPUB support is still in beta. If you find bugs, please report them by opening a ticket.').exec_() + prefs['output_format'] = of if not path or not os.path.exists(path) or not os.path.isdir(path): d = error_dialog(self, _('Invalid database location'), diff --git a/src/calibre/gui2/dialogs/config.ui b/src/calibre/gui2/dialogs/config.ui index 59fa9942d7..b56d9cffb5 100644 --- a/src/calibre/gui2/dialogs/config.ui +++ b/src/calibre/gui2/dialogs/config.ui @@ -7,7 +7,7 @@ 0 0 709 - 685 + 676 @@ -22,15 +22,9 @@ - - - 0 - 0 - - - 100 + 140 16777215 @@ -40,10 +34,22 @@ true + + true + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + - 32 - 32 + 48 + 48 @@ -55,11 +61,8 @@ false - - - 80 - 80 - + + 25 QListView::IconMode @@ -78,14 +81,6 @@ 0 - - - 0 - 0 - 595 - 640 - - @@ -125,33 +120,6 @@ - - - - Use &Roman numerals for series number - - - true - - - - - - - - - &Number of covers to show in browse mode (after restart): - - - cover_browse - - - - - - - - @@ -166,9 +134,22 @@ + + + + If you disable this setting, metadatas is guessed from the filename instead. This can be configured in the Advanced section. + + + Read &metadata from files + + + true + + + - + Format for &single file save: @@ -178,10 +159,10 @@ - + - + &Priority for conversion jobs: @@ -191,10 +172,10 @@ - + - + Default network &timeout: @@ -204,7 +185,7 @@ - + Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information) @@ -223,72 +204,48 @@ + + + + + + + Choose &language (requires restart): + + + language + + + + + + + The default output format for ebook conversions. + + + + LRF + + + + + EPUB + + + + + + + + &Output format: + + + output_format + + + - - - - Toolbar - - - - - - - Large - - - - - Medium - - - - - Small - - - - - - - - &Button size in toolbar - - - toolbar_button_size - - - - - - - Show &text in toolbar buttons - - - true - - - - - - - - - - Select visible &columns in library view - - - - - - QAbstractItemView::NoSelection - - - - - - @@ -388,15 +345,102 @@ + + + + + + Use &Roman numerals for series number + + + true + + + + + + + + + &Number of covers to show in browse mode (after restart): + + + cover_browse + + + + + + + + + + + + Toolbar + + + + + + + Large + + + + + Medium + + + + + Small + + + + + + + + &Button size in toolbar + + + toolbar_button_size + + + + + + + Show &text in toolbar buttons + + + true + + + + + + + + + + Select visible &columns in library view + + + + + + QAbstractItemView::NoSelection + + + + + + + + - - - 0 - 0 - 595 - 638 - - @@ -489,8 +533,8 @@ accept() - 231 - 502 + 235 + 671 157 @@ -505,8 +549,8 @@ reject() - 299 - 502 + 303 + 671 286 @@ -521,12 +565,12 @@ setCurrentIndex(int) - 176 - 184 + 142 + 117 - 294 - 9 + 256 + 7 diff --git a/src/calibre/gui2/dialogs/epub.py b/src/calibre/gui2/dialogs/epub.py new file mode 100644 index 0000000000..8bd5ef9331 --- /dev/null +++ b/src/calibre/gui2/dialogs/epub.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +The GUI for conversion to EPUB. +''' +import os + +from PyQt4.Qt import QDialog, QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, \ + QTextEdit, QCheckBox, Qt, QPixmap, QIcon, QListWidgetItem, SIGNAL +from lxml.etree import XPath + +from calibre.gui2.dialogs.choose_format import ChooseFormatDialog +from calibre.gui2.dialogs.epub_ui import Ui_Dialog +from calibre.gui2 import error_dialog, choose_images, pixmap_to_data +from calibre.ebooks.epub.from_any import SOURCE_FORMATS, config +from calibre.ebooks.metadata import MetaInformation +from calibre.ptempfile import PersistentTemporaryFile +from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.metadata import authors_to_string, string_to_authors + + +class Config(QDialog, Ui_Dialog): + + def __init__(self, parent, db, row=None): + QDialog.__init__(self, parent) + self.setupUi(self) + self.connect(self.category_list, SIGNAL('itemEntered(QListWidgetItem *)'), + self.show_category_help) + self.connect(self.cover_button, SIGNAL("clicked()"), self.select_cover) + + self.cover_changed = False + self.db = db + self.id = None + self.row = row + if row is not None: + self.id = db.id(row) + base = config().as_string() + '\n\n' + defaults = self.db.conversion_options(self.id, 'epub') + defaults = base + (defaults if defaults else '') + self.config = config(defaults=defaults) + else: + self.config = config() + self.initialize() + self.get_source_format() + self.category_list.setCurrentRow(0) + if self.row is None: + self.setWindowTitle(_('Bulk convert to EPUB')) + else: + self.setWindowTitle(_(u'Convert %s to EPUB')%unicode(self.title.text())) + + def initialize(self): + self.__w = [] + self.__w.append(QIcon(':/images/dialog_information.svg')) + self.item1 = QListWidgetItem(self.__w[-1], _('Metadata'), self.category_list) + self.__w.append(QIcon(':/images/lookfeel.svg')) + self.item2 = QListWidgetItem(self.__w[-1], _('Look & Feel'), self.category_list) + self.__w.append(QIcon(':/images/page.svg')) + self.item3 = QListWidgetItem(self.__w[-1], _('Page Setup'), self.category_list) + self.__w.append(QIcon(':/images/chapters.svg')) + self.item4 = QListWidgetItem(self.__w[-1], _('Chapter Detection'), self.category_list) + self.setup_tooltips() + self.initialize_options() + + def set_help(self, msg): + if msg and getattr(msg, 'strip', lambda:True)(): + self.help_view.setPlainText(msg) + + def setup_tooltips(self): + for opt in self.config.option_set.preferences: + g = getattr(self, 'opt_'+opt.name, False) + if opt.help and g: + help = opt.help.replace('%default', str(opt.default)) + g._help = help + g.setToolTip(help.replace('<', '<').replace('>', '>')) + g.setWhatsThis(help.replace('<', '<').replace('>', '>')) + g.__class__.enterEvent = lambda obj, event: self.set_help(getattr(obj, '_help', obj.toolTip())) + + def show_category_help(self, item): + text = unicode(item.text()) + help = { + _('Metadata') : _('Specify metadata such as title and author for the book.\n\nMetadata will be updated in the database as well as the generated EPUB file.'), + _('Look & Feel') : _('Adjust the look of the generated EPUB file by specifying things like font sizes.'), + _('Page Setup') : _('Specify the page layout settings like margins.'), + _('Chapter Detection') : _('Fine tune the detection of chapter and section headings.'), + } + self.set_help(help[text]) + + def select_cover(self): + files = choose_images(self, 'change cover dialog', + _('Choose cover for ') + unicode(self.title.text())) + if not files: + return + _file = files[0] + if _file: + _file = os.path.abspath(_file) + if not os.access(_file, os.R_OK): + d = error_dialog(self.window, _('Cannot read'), + _('You do not have permission to read the file: ') + _file) + d.exec_() + return + cf, cover = None, None + try: + cf = open(_file, "rb") + cover = cf.read() + except IOError, e: + d = error_dialog(self.window, _('Error reading file'), + _("

There was an error reading from file:
") + _file + "


"+str(e)) + d.exec_() + if cover: + pix = QPixmap() + pix.loadFromData(cover) + if pix.isNull(): + d = error_dialog(self.window, _file + _(" is not a valid picture")) + d.exec_() + else: + self.cover_path.setText(_file) + self.cover.setPixmap(pix) + self.cover_changed = True + self.cpixmap = pix + + def initialize_metadata_options(self): + all_series = self.db.all_series() + all_series.sort(cmp=lambda x, y : cmp(x[1], y[1])) + for series in all_series: + self.series.addItem(series[1]) + self.series.setCurrentIndex(-1) + + if self.row is not None: + mi = self.db.get_metadata(self.id, index_is_id=True) + self.title.setText(mi.title) + if mi.authors: + self.author.setText(authors_to_string(mi.authors)) + else: + self.author.setText('') + self.publisher.setText(mi.publisher if mi.publisher else '') + self.author_sort.setText(mi.author_sort if mi.author_sort else '') + self.tags.setText(', '.join(mi.tags if mi.tags else [])) + self.comment.setText(mi.comments if mi.comments else '') + if mi.series: + self.series.setCurrentIndex(self.series.findText(mi.series)) + if mi.series_index is not None: + self.series_index.setValue(mi.series_index) + + cover = self.db.cover(self.id, index_is_id=True) + if cover: + pm = QPixmap() + pm.loadFromData(cover) + if not pm.isNull(): + self.cover.setPixmap(pm) + + def get_title_and_authors(self): + title = unicode(self.title.text()).strip() + if not title: + title = _('Unknown') + authors = unicode(self.author.text()).strip() + authors = string_to_authors(authors) if authors else [_('Unknown')] + return title, authors + + def get_metadata(self): + title, authors = self.get_title_and_authors() + mi = MetaInformation(title, authors) + publisher = unicode(self.publisher.text()) + if publisher: + mi.publisher = publisher + author_sort = unicode(self.author_sort.text()) + if author_sort: + mi.author_sort = author_sort + comments = unicode(self.comment.toPlainText()) + if comments: + mi.comments = comments + mi.series_index = int(self.series_index.value()) + if self.series.currentIndex() > -1: + mi.series = unicode(self.series.currentText()) + tags = [t.strip() for t in unicode(self.tags.text()).split(',')] + if tags: + mi.tags = tags + + return mi + + def read_settings(self): + for pref in self.config.option_set.preferences: + g = getattr(self, 'opt_'+pref.name, False) + if g: + if isinstance(g, (QSpinBox, QDoubleSpinBox)): + self.config.set(pref.name, g.value()) + elif isinstance(g, (QLineEdit, QTextEdit)): + func = getattr(g, 'toPlainText', getattr(g, 'text', None))() + val = unicode(func) + self.config.set(pref.name, val if val else None) + elif isinstance(g, QComboBox): + self.config.set(pref.name, unicode(g.currentText())) + elif isinstance(g, QCheckBox): + self.config.set(pref.name, bool(g.isChecked())) + if self.row is not None: + self.db.set_conversion_options(self.id, 'epub', self.config.src) + + + def initialize_options(self): + self.initialize_metadata_options() + values = self.config.parse() + for pref in self.config.option_set.preferences: + g = getattr(self, 'opt_'+pref.name, False) + if g: + val = getattr(values, pref.name) + if val is None: + continue + if isinstance(g, (QSpinBox, QDoubleSpinBox)): + g.setValue(val) + elif isinstance(g, (QLineEdit, QTextEdit)): + getattr(g, 'setPlainText', g.setText)(val) + elif isinstance(g, QComboBox): + for value in pref.choices: + g.addItem(value) + g.setCurrentIndex(g.findText(val)) + elif isinstance(g, QCheckBox): + g.setCheckState(Qt.Checked if bool(val) else Qt.Unchecked) + + + def get_source_format(self): + self.source_format = None + if self.row is not None: + temp = self.db.formats(self.id, index_is_id=True) + if not temp: + error_dialog(self.parent(), _('Cannot convert'), + _('This book has no available formats')).exec_() + + available_formats = [f.upper().strip() for f in temp.split(',')] + choices = [fmt.upper() for fmt in SOURCE_FORMATS if fmt.upper() in available_formats] + if not choices: + error_dialog(self.parent(), _('No available formats'), + _('Cannot convert %s as this book has no supported formats')%(self.title.text())).exec_() + elif len(choices) == 1: + self.source_format = choices[0] + else: + d = ChooseFormatDialog(self.parent(), _('Choose the format to convert to EPUB'), choices) + if d.exec_() == QDialog.Accepted: + self.source_format = d.format() + + def accept(self): + for opt in ('chapter', 'level1_toc', 'level2_toc'): + text = unicode(getattr(self, 'opt_'+opt).text()) + if text: + try: + XPath(text,namespaces={'re':'http://exslt.org/regular-expressions'}) + except Exception, err: + error_dialog(self, _('Invalid XPath expression'), + _('The expression %s is invalid. Error: %s')%(text, err) + ).exec_() + return + mi = self.get_metadata() + self.read_settings() + self.cover_file = None + if self.row is not None: + self.db.set_metadata(self.id, mi) + self.mi = self.db.get_metadata(self.id, index_is_id=True) + opf = OPFCreator(os.getcwdu(), self.mi) + self.opf_file = PersistentTemporaryFile('.opf') + opf.render(self.opf_file) + self.opf_file.close() + if self.cover_changed: + self.db.set_cover(self.id, pixmap_to_data(self.cover.pixmap())) + cover = self.db.cover(self.id, index_is_id=True) + if cover: + cf = PersistentTemporaryFile('.jpeg') + cf.write(cover) + cf.close() + self.cover_file = cf + self.opts = self.config.parse() + QDialog.accept(self) + + \ No newline at end of file diff --git a/src/calibre/gui2/dialogs/epub.ui b/src/calibre/gui2/dialogs/epub.ui new file mode 100644 index 0000000000..34836a3b04 --- /dev/null +++ b/src/calibre/gui2/dialogs/epub.ui @@ -0,0 +1,805 @@ + + Dialog + + + + 0 + 0 + 868 + 670 + + + + Convert to EPUB + + + + :/images/convert.svg:/images/convert.svg + + + true + + + + + + + + + 172 + 16777215 + + + + + 75 + true + + + + true + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + 48 + 48 + + + + QListView::TopToBottom + + + false + + + 10 + + + QListView::IconMode + + + true + + + -1 + + + + + + + 0 + + + + + + + + + Book Cover + + + + + + 6 + + + 0 + + + + + Change &cover image: + + + cover_path + + + + + + + 6 + + + 0 + + + + + true + + + + + + + Browse for an image to use as the cover of this book. + + + ... + + + + :/images/document_open.svg:/images/document_open.svg + + + + + + + + + + + Use cover from &source file + + + true + + + + + + + + + + + + :/images/book.svg + + + true + + + Qt::AlignCenter + + + + + + + opt_prefer_metadata_cover + + + + + + + + + + + &Title: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + title + + + + + + + Change the title of this book + + + + + + + &Author(s): + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + author + + + + + + + + 1 + 0 + + + + Change the author(s) of this book. Multiple authors should be separated by an &. If the author name contains an &, use && to represent it. + + + + + + + Author So&rt: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + author_sort + + + + + + + + 0 + 0 + + + + Change the author(s) of this book. Multiple authors should be separated by a comma + + + + + + + &Publisher: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + publisher + + + + + + + Change the publisher of this book + + + + + + + Ta&gs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + tags + + + + + + + Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas. + + + + + + + &Series: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + series + + + + + + + + 10 + 0 + + + + List of known series. You can add new series. + + + List of known series. You can add new series. + + + true + + + QComboBox::InsertAlphabetically + + + QComboBox::AdjustToContents + + + + + + + true + + + Series index. + + + Series index. + + + Book + + + 1 + + + 10000 + + + + + + + + + + 0 + 0 + + + + + 16777215 + 200 + + + + Comments + + + + + + + 16777215 + 180 + + + + + + + + + + + + + + + + + + + + + Source en&coding: + + + opt_encoding + + + + + + + + + + Base &font size: + + + opt_base_font_size2 + + + + + + + pt + + + 0 + + + 0.000000000000000 + + + 30.000000000000000 + + + 1.000000000000000 + + + 30.000000000000000 + + + + + + + Remove &spacing between paragraphs + + + + + + + + + Override &CSS + + + + + + + + + + + + + + + + &Profile: + + + opt_profile + + + + + + + -1 + + + 1 + + + + + + + &Left Margin: + + + opt_margin_left + + + + + + + pt + + + 200 + + + 20 + + + + + + + &Right Margin: + + + opt_margin_right + + + + + + + pt + + + 200 + + + 20 + + + + + + + &Top Margin: + + + opt_margin_top + + + + + + + pt + + + 200 + + + 10 + + + + + + + &Bottom Margin: + + + opt_margin_bottom + + + + + + + pt + + + 200 + + + 0 + + + + + + + + + + + Automatic &chapter detection + + + + + + &XPath: + + + opt_chapter + + + + + + + + + + <!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> + + + Qt::RichText + + + true + + + + + + + + + + Chapter &mark: + + + opt_chapter_mark + + + + + + + + + + Automatic &Table of Contents + + + + + + + + + Number of &links to add to Table of Contents + + + opt_max_toc_links + + + + + + + Do not add &detected chapters to the Table of Contents + + + + + + + + + + Chapter &threshold + + + opt_toc_threshold + + + + + + + &Force use of auto-generated Table of Contents + + + + + + + + + + Level &1 TOC + + + opt_level1_toc + + + + + + + Level &2 TOC + + + opt_level2_toc + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + 16777215 + 100 + + + + false + + + + + + + + ImageView + QLabel +
widgets.h
+
+
+ + + + + + + buttonBox + accepted() + Dialog + accept() + + + 222 + 652 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 290 + 658 + + + 286 + 274 + + + + + category_list + currentRowChanged(int) + stack + setCurrentIndex(int) + + + 88 + 42 + + + 659 + 12 + + + + +
diff --git a/src/calibre/gui2/dialogs/lrf_single.py b/src/calibre/gui2/dialogs/lrf_single.py index 787df4d080..9f905c4458 100644 --- a/src/calibre/gui2/dialogs/lrf_single.py +++ b/src/calibre/gui2/dialogs/lrf_single.py @@ -14,6 +14,7 @@ from calibre.gui2.widgets import FontFamilyModel from calibre.ebooks.lrf import option_parser from calibre.ptempfile import PersistentTemporaryFile from calibre.constants import __appname__ +from calibre.ebooks.metadata import authors_to_string, string_to_authors, authors_to_sort_string font_family_model = None @@ -199,7 +200,11 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): self.id = self.db.id(row) self.gui_title.setText(db.title(row)) au = self.db.authors(row) - self.gui_author.setText(au if au else '') + if au: + au = [a.strip().replace('|', ',') for a in au.split(',')] + self.gui_author.setText(authors_to_string(au)) + else: + self.gui_author.setText('') aus = self.db.author_sort(row) self.gui_author_sort.setText(aus if aus else '') pub = self.db.publisher(row) @@ -350,14 +355,16 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): def write_metadata(self): title = qstring_to_unicode(self.gui_title.text()) self.db.set_title(self.id, title) - au = qstring_to_unicode(self.gui_author.text()).split(',') - if au: self.db.set_authors(self.id, au) + au = unicode(self.gui_author.text()) + if au: + self.db.set_authors(self.id, string_to_authors(au)) aus = qstring_to_unicode(self.gui_author_sort.text()) if not aus: t = self.db.authors(self.id, index_is_id=True) if not t: - t = 'Unknown' - aus = t.split(',')[0].strip() + t = _('Unknown') + aus = [a.strip().replace('|', ',') for a in t.split(',')] + aus = authors_to_sort_string(aus) self.db.set_author_sort(self.id, aus) self.db.set_publisher(self.id, qstring_to_unicode(self.gui_publisher.text())) self.db.set_tags(self.id, qstring_to_unicode(self.tags.text()).split(',')) diff --git a/src/calibre/gui2/dialogs/lrf_single.ui b/src/calibre/gui2/dialogs/lrf_single.ui index c63e4915b7..f08265fe9e 100644 --- a/src/calibre/gui2/dialogs/lrf_single.ui +++ b/src/calibre/gui2/dialogs/lrf_single.ui @@ -115,17 +115,9 @@ - 3 + 0 - - - 0 - 0 - 642 - 458 - - @@ -263,7 +255,7 @@ - Change the author(s) of this book. Multiple authors should be separated by a comma + Change the author(s) of this book. Multiple authors should be separated by an &. If the author name contains an &, use && to represent it. @@ -431,14 +423,6 @@ - - - 0 - 0 - 642 - 458 - - @@ -697,14 +681,6 @@ - - - 0 - 0 - 642 - 458 - - @@ -742,7 +718,7 @@ px - 100 + 200 20 @@ -765,7 +741,7 @@ px - 100 + 200 20 @@ -788,7 +764,7 @@ px - 100 + 200 10 @@ -811,7 +787,7 @@ px - 100 + 200 0 @@ -854,14 +830,6 @@ - - - 0 - 0 - 642 - 458 - - @@ -1017,7 +985,7 @@ <!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:'Candara'; font-size:11pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <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:'Sans Serif'; font-size:9pt;"></p></body></html> diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 99175b656b..fac7d7be85 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -9,6 +9,7 @@ from PyQt4.QtGui import QDialog from calibre.gui2 import qstring_to_unicode from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog from calibre.gui2.dialogs.tag_editor import TagEditor +from calibre.ebooks.metadata import string_to_authors class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): def __init__(self, window, rows, db): @@ -29,6 +30,11 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): id, name = i self.series.addItem(name) + for f in self.db.all_formats(): + self.remove_format.addItem(f) + + self.remove_format.setCurrentIndex(-1) + self.series.lineEdit().setText('') QObject.connect(self.series, SIGNAL('currentIndexChanged(int)'), self.series_changed) QObject.connect(self.series, SIGNAL('editTextChanged(QString)'), self.series_changed) @@ -46,7 +52,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): for id in self.ids: au = qstring_to_unicode(self.authors.text()) if au: - au = au.split(',') + au = string_to_authors(au) self.db.set_authors(id, au) aus = qstring_to_unicode(self.author_sort.text()) if aus: @@ -66,7 +72,11 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.db.unapply_tags(id, remove_tags) if self.write_series: self.db.set_series(id, qstring_to_unicode(self.series.currentText())) - self.changed = True + + if self.remove_format.currentIndex() > -1: + self.db.remove_format(id, unicode(self.remove_format.currentText()), index_is_id=True) + + self.changed = True def series_changed(self): self.write_series = True diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index 1b7929cdc6..b4a4106d87 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -52,7 +52,7 @@ - Change the author(s) of this book. Multiple authors should be separated by a comma + Change the author(s) of this book. Multiple authors should be separated by an &. If the author name contains an &, use && to represent it. @@ -84,6 +84,9 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + rating + @@ -211,6 +214,19 @@ + + + + + + + Remove &format: + + + remove_format + + +
diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index fa6ea780d2..c6e26e86dc 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -17,6 +17,7 @@ from calibre.gui2.dialogs.fetch_metadata import FetchMetadata from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.dialogs.password import PasswordDialog from calibre.ebooks import BOOK_EXTENSIONS +from calibre.ebooks.metadata import authors_to_sort_string, string_to_authors, authors_to_string from calibre.ebooks.metadata.library_thing import login, cover_from_isbn, LibraryThingError from calibre import islinux from calibre.utils.config import prefs @@ -100,7 +101,7 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): old_extensions, new_extensions, paths = set(), set(), {} for row in range(self.formats.count()): fmt = self.formats.item(row) - ext, path = fmt.ext, fmt.path + ext, path = fmt.ext.lower(), fmt.path if 'unknown' in ext.lower(): ext = None if path: @@ -109,8 +110,8 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): else: old_extensions.add(ext) for ext in new_extensions: - self.db.add_format(self.row, ext, open(paths[ext], "rb")) - db_extensions = set(self.db.formats(self.row).split(',')) + self.db.add_format(self.row, ext, open(paths[ext], 'rb')) + db_extensions = set([f.lower() for f in self.db.formats(self.row).split(',')]) extensions = new_extensions.union(old_extensions) for ext in db_extensions: if ext not in extensions: @@ -144,7 +145,9 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): QObject.connect(self.tag_editor_button, SIGNAL('clicked()'), self.edit_tags) QObject.connect(self.remove_series_button, SIGNAL('clicked()'), - self.remove_unused_series) + self.remove_unused_series) + QObject.connect(self.auto_author_sort, SIGNAL('clicked()'), + self.deduce_author_sort) self.connect(self.swap_button, SIGNAL('clicked()'), self.swap_title_author) self.timeout = float(prefs['network_timeout']) self.title.setText(db.title(row)) @@ -153,7 +156,11 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): isbn = '' self.isbn.setText(isbn) au = self.db.authors(row) - self.authors.setText(au if au else '') + if au: + au = [a.strip().replace('|', ',') for a in au.split(',')] + self.authors.setText(authors_to_string(au)) + else: + self.authors.setText('') aus = self.db.author_sort(row) self.author_sort.setText(aus if aus else '') pub = self.db.publisher(row) @@ -195,6 +202,11 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): if not pm.isNull(): self.cover.setPixmap(pm) + def deduce_author_sort(self): + au = unicode(self.authors.text()) + authors = string_to_authors(au) + self.author_sort.setText(authors_to_sort_string(authors)) + def swap_title_author(self): title = self.title.text() self.title.setText(self.authors.text()) @@ -281,7 +293,7 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): def fetch_metadata(self): isbn = qstring_to_unicode(self.isbn.text()) title = qstring_to_unicode(self.title.text()) - author = qstring_to_unicode(self.authors.text()).split(',')[0] + author = string_to_authors(unicode(self.authors.text()))[0] publisher = qstring_to_unicode(self.publisher.text()) if isbn or title or author or publisher: d = FetchMetadata(self, isbn, title, author, publisher, self.timeout) @@ -290,10 +302,10 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): book = d.selected_book() if book: self.title.setText(book.title) - self.authors.setText(', '.join(book.authors)) + self.authors.setText(authors_to_string(book.authors)) if book.author_sort: self.author_sort.setText(book.author_sort) - self.publisher.setText(book.publisher) - self.isbn.setText(book.isbn) + if book.publisher: self.publisher.setText(book.publisher) + if book.isbn: self.isbn.setText(book.isbn) summ = book.comments if summ: prefix = qstring_to_unicode(self.comments.toPlainText()) @@ -323,8 +335,9 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog): self.sync_formats() title = qstring_to_unicode(self.title.text()) self.db.set_title(self.id, title) - au = qstring_to_unicode(self.authors.text()).split(',') - if au: self.db.set_authors(self.id, au) + au = unicode(self.authors.text()) + if au: + self.db.set_authors(self.id, string_to_authors(au)) aus = qstring_to_unicode(self.author_sort.text()) if aus: self.db.set_author_sort(self.id, aus) diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 82dbfebb71..3f82f81039 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -5,7 +5,7 @@ 0 0 - 796 + 923 715 @@ -98,7 +98,7 @@ - Change the author(s) of this book. Multiple authors should be separated by a comma + Change the author(s) of this book. Multiple authors should be separated by an &. If the author name contains an &, use && to represent it. @@ -116,11 +116,29 @@
- - - Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles. - - + + + + + Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles. + + + + + + + Automatically create the author sort entry based on the current author entry + + + ... + + + + :/images/auto_author_sort.svg:/images/auto_author_sort.svg + + + + @@ -320,16 +338,11 @@ Comments - - - - 9 - 39 - 354 - 557 - - - + + + + + @@ -436,8 +449,8 @@ Book Cover - - + + @@ -456,11 +469,14 @@ - + 6 + + QLayout::SetMaximumSize + 0 @@ -507,7 +523,7 @@ - + diff --git a/src/calibre/gui2/dialogs/password.py b/src/calibre/gui2/dialogs/password.py index 31e01a25cf..e95f1c53a3 100644 --- a/src/calibre/gui2/dialogs/password.py +++ b/src/calibre/gui2/dialogs/password.py @@ -16,7 +16,7 @@ class PasswordDialog(QDialog, Ui_Dialog): self.cfg_key = re.sub(r'[^0-9a-zA-Z]', '_', name) un = dynamic[self.cfg_key+'__un'] - pw = dynamic[self.cfg_key+'__un'] + pw = dynamic[self.cfg_key+'__pw'] if not un: un = '' if not pw: pw = '' self.gui_username.setText(un) diff --git a/src/calibre/gui2/dialogs/warning.ui b/src/calibre/gui2/dialogs/warning.ui new file mode 100644 index 0000000000..11c2e95cad --- /dev/null +++ b/src/calibre/gui2/dialogs/warning.ui @@ -0,0 +1,113 @@ + + Dialog + + + + 0 + 0 + 727 + 432 + + + + Dialog + + + + :/images/dialog_warning.svg:/images/dialog_warning.svg + + + + + + TextLabel + + + true + + + + + + + + + + + + + + :/images/dialog_warning.svg + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/calibre/gui2/images/add_book.svg b/src/calibre/gui2/images/add_book.svg index a2b1a1901d..b0633d48d3 100644 --- a/src/calibre/gui2/images/add_book.svg +++ b/src/calibre/gui2/images/add_book.svg @@ -1991,7 +1991,7 @@ cx="343.99899" rx="8.0010004" r="36" - style="fill:url(#linearGradient5167);fill-opacity:1" + style="fill-opacity:1" sodipodi:cx="343.99899" sodipodi:cy="92" sodipodi:rx="36" diff --git a/src/calibre/gui2/images/auto_author_sort.svg b/src/calibre/gui2/images/auto_author_sort.svg new file mode 100644 index 0000000000..edcf9e4704 --- /dev/null +++ b/src/calibre/gui2/images/auto_author_sort.svg @@ -0,0 +1,1472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/calibre/gui2/images/mimetypes/epub.svg b/src/calibre/gui2/images/mimetypes/epub.svg new file mode 100644 index 0000000000..cafef17b80 --- /dev/null +++ b/src/calibre/gui2/images/mimetypes/epub.svg @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/src/calibre/gui2/images/mimetypes/lit.svg b/src/calibre/gui2/images/mimetypes/lit.svg index 849ccd0fd6..a38f66e2cc 100644 --- a/src/calibre/gui2/images/mimetypes/lit.svg +++ b/src/calibre/gui2/images/mimetypes/lit.svg @@ -5145,7 +5145,7 @@ id="stop16206" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/calibre/gui2/images/plus.svg b/src/calibre/gui2/images/plus.svg index af011703ff..50a22437a7 100644 --- a/src/calibre/gui2/images/plus.svg +++ b/src/calibre/gui2/images/plus.svg @@ -7,239 +7,48 @@ xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" - id="svg1307" + id="svg2936" sodipodi:version="0.32" - inkscape:version="0.43" + inkscape:version="0.45+devel" version="1.0" - sodipodi:docbase="/home/pinheiro/Documents/pics/new oxygen/svg" - sodipodi:docname="plus.svg"> + sodipodi:docname="edit-add.svgz" + inkscape:output_extension="org.inkscape.output.svgz.inkscape"> - - - - - - - - - - - - - - + id="defs2938"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xlink:href="#XMLID_4_" + id="linearGradient4284" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.4999996,0,0,2.4999996,174,-145.99998)" + x1="-13.757333" + y1="76.708466" + x2="-62.424866" + y2="104.80668" /> - - - - - - - - - - - - - - - + xlink:href="#linearGradient3260" + id="linearGradient4299" + gradientUnits="userSpaceOnUse" + spreadMethod="reflect" + x1="73.742638" + y1="15.336544" + x2="80" + y2="19.281664" /> - - - - - - - - - - - + xlink:href="#linearGradient3260" + id="linearGradient4297" + gradientUnits="userSpaceOnUse" + spreadMethod="reflect" + x1="73.742638" + y1="15.336544" + x2="80" + y2="19.281664" /> + id="linearGradient5412" + gradientUnits="userSpaceOnUse" + x1="28" + y1="57.5" + x2="28" + y2="0"> + style="stop-color:#fff14d;stop-opacity:1;" + id="stop5414" /> + style="stop-color:#f8ffa0;stop-opacity:0;" + id="stop5416" /> + + + + + + xlink:href="#linearGradient3030" + id="radialGradient4275" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.4999996,0,0,2.4999996,174,-145.99998)" + cx="-44" + cy="84" + fx="-60" + fy="100" + r="24" /> + + + + + + + + + + + - + + + + + - + + + + + + + + + + + + + + + x1="97.622581" + y1="77.512512" + x2="98.097946" + y2="105.10625" + gradientTransform="translate(-36.000006,-20.000008)" /> - + - - - - - - - - - - - - - - - - - - - - - - - - + gradientTransform="scale(1.039383,0.9621093)" + x1="64.341991" + y1="18.50366" + x2="76.284438" + y2="18.50366" /> - + inkscape:current-layer="layer1" + height="128px" + width="128px" + gridtolerance="10000" + inkscape:window-width="976" + inkscape:window-height="904" + inkscape:window-x="260" + inkscape:window-y="43"> + + id="metadata2941"> image/svg+xml - - - - Oxygen team - - - - - - - - - - + inkscape:label="Livello 1" + inkscape:groupmode="layer" + id="layer1"> + style="fill:url(#linearGradient4284);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 59.156262,4 C 50.862445,4 44.000004,10.862442 44.000004,19.156248 L 44.000004,43.999993 L 19.156259,43.999993 C 10.862452,43.999993 4.0000112,50.862435 4.0000112,59.156236 L 4.0000112,68.843735 C 4.0000112,77.137559 10.862452,83.999983 19.156259,83.999983 L 44.000004,83.999983 L 44.000004,108.84375 C 44.000004,117.13755 50.862451,124 59.156262,124 L 68.843765,124 C 77.137555,124 84.000005,117.13755 84.000005,108.84375 L 84.000005,83.999983 L 108.84376,83.999983 C 117.13756,83.999983 124,77.137559 124,68.843735 L 124,59.156236 C 124,50.862435 117.13756,43.999993 108.84376,43.999993 L 84.000005,43.999993 L 84.000005,19.156248 C 84.000005,10.862442 77.137555,4 68.843765,4 L 59.156262,4 z" + id="path3012" + sodipodi:nodetypes="ccccccccccccccccccccc" + clip-path="none" /> + sodipodi:nodetypes="cccccc" + transform="matrix(-1.2499999,0,0,1.2499999,144.00001,-10.102078)" + id="path3091" + d="M 69.875971,12.057888 C 68.798883,12.123171 67.34775,12.277052 66.875971,12.995388 L 68.465655,24.133449 L 79,23.37409 L 79,22.90534 C 80.740958,20.33518 74.219552,11.998548 69.875971,12.057888 z" + style="fill:url(#linearGradient4299);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" + clip-path="none" /> + style="fill:url(#linearGradient4297);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" + d="M 69.875971,12.057888 C 68.798883,12.123171 67.34775,12.277052 66.875971,12.995388 L 68.172686,21.789699 L 79,23.37409 L 79,22.90534 C 80.740958,20.33518 74.219552,11.998548 69.875971,12.057888 z" + id="path3095" + transform="matrix(1.2499999,0,0,1.2499999,-15.110921,-10.102078)" + sodipodi:nodetypes="cccccc" + clip-path="none" /> + style="opacity:0.68164804;fill:url(#linearGradient3003);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" + d="M 69.875971,12.057888 C 68.798883,12.123171 67.34775,12.277052 66.875971,12.995388 L 69.051593,23.742824 L 79,23.37409 L 79,22.90534 C 80.740958,20.33518 74.219552,11.998548 69.875971,12.057888 z" + id="path3197" + transform="matrix(-1.2499999,0,0,-1.2499999,144.00001,139.07195)" + sodipodi:nodetypes="cccccc" /> + sodipodi:nodetypes="cccccc" + transform="matrix(1.2499999,0,0,-1.2499999,-15.110911,139.07195)" + id="path3199" + d="M 69.875971,12.057888 C 68.798883,12.123171 67.34775,12.277052 66.875971,12.995388 L 67.782061,23.547512 L 79,23.37409 L 79,22.90534 C 80.740958,20.33518 74.219552,11.998548 69.875971,12.057888 z" + style="opacity:0.70786516;fill:url(#linearGradient3005);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" /> + sodipodi:nodetypes="cccccc" + transform="matrix(1.2499999,0,0,1.2499999,24.889073,28.928032)" + id="path3221" + d="M 69.875971,12.057888 C 68.798883,12.123171 67.34775,12.277052 66.875971,12.995388 L 68.465655,24.133449 L 79,23.37409 L 79,22.90534 C 80.740958,20.33518 74.219552,11.998548 69.875971,12.057888 z" + style="opacity:0.55056176;fill:url(#linearGradient4291);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" + clip-path="none" /> + sodipodi:nodetypes="ccccccccccccccccccccc" + id="path3028" + d="M 59.156262,4 C 50.862445,4 44.000004,10.862442 44.000004,19.156248 L 44.000004,43.999993 L 19.156259,43.999993 C 10.862452,43.999993 4.000007,47.134768 4.000007,55.428569 C 4.000008,53.062884 4.00001,63.906397 4.000011,68.843735 C 4.000011,77.137559 10.862452,83.999983 19.156259,83.999983 L 44.000004,83.999983 L 44.000004,108.84375 C 44.000004,117.13755 50.862451,124 59.156262,124 L 68.843765,124 C 77.13756,124 84.00001,117.13755 84.00001,108.84375 L 84.00001,83.999983 L 108.84376,83.999983 C 117.13756,83.999983 124,77.137559 124,68.843735 L 124,59.156236 C 124,50.862435 117.13756,43.999993 108.84376,43.999993 L 84.00001,43.999993 L 84.00001,19.156248 C 84.00001,10.862442 77.13756,4 68.843765,4 L 59.156262,4 z" + style="opacity:0.58052434;fill:url(#radialGradient4275);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + clip-path="none" /> + + + + + + diff --git a/src/calibre/gui2/images/publisher.png b/src/calibre/gui2/images/publisher.png new file mode 100644 index 0000000000..d3ff9aaf02 Binary files /dev/null and b/src/calibre/gui2/images/publisher.png differ diff --git a/src/calibre/gui2/images/series.svg b/src/calibre/gui2/images/series.svg new file mode 100644 index 0000000000..c26d1ef7a2 --- /dev/null +++ b/src/calibre/gui2/images/series.svg @@ -0,0 +1,1096 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/calibre/gui2/images/tags.svg b/src/calibre/gui2/images/tags.svg new file mode 100644 index 0000000000..608f637c82 --- /dev/null +++ b/src/calibre/gui2/images/tags.svg @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Oxygen team + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/calibre/gui2/jobs2.py b/src/calibre/gui2/jobs2.py index 9b30a3190e..109c4eaa33 100644 --- a/src/calibre/gui2/jobs2.py +++ b/src/calibre/gui2/jobs2.py @@ -19,13 +19,13 @@ NONE = QVariant() class JobManager(QAbstractTableModel): - wait_icon = QVariant(QIcon(':/images/jobs.svg')) - running_icon = QVariant(QIcon(':/images/exec.svg')) - error_icon = QVariant(QIcon(':/images/dialog_error.svg')) - done_icon = QVariant(QIcon(':/images/ok.svg')) - def __init__(self): QAbstractTableModel.__init__(self) + self.wait_icon = QVariant(QIcon(':/images/jobs.svg')) + self.running_icon = QVariant(QIcon(':/images/exec.svg')) + self.error_icon = QVariant(QIcon(':/images/dialog_error.svg')) + self.done_icon = QVariant(QIcon(':/images/ok.svg')) + self.jobs = [] self.server = Server() self.add_job = Dispatcher(self._add_job) @@ -42,13 +42,13 @@ class JobManager(QAbstractTableModel): def headerData(self, section, orientation, role): if role != Qt.DisplayRole: return NONE - if orientation == Qt.Horizontal: + if orientation == Qt.Horizontal: if section == 0: text = _("Job") elif section == 1: text = _("Status") elif section == 2: text = _("Progress") elif section == 3: text = _('Running time') return QVariant(text) - else: + else: return QVariant(section+1) def data(self, index, role): @@ -58,7 +58,7 @@ class JobManager(QAbstractTableModel): row, col = index.row(), index.column() job = self.jobs[row] - if role == Qt.DisplayRole: + if role == Qt.DisplayRole: if col == 0: desc = job.description if not desc: @@ -145,7 +145,7 @@ class JobManager(QAbstractTableModel): return True return False - def run_job(self, done, func, args=[], kwargs={}, + def run_job(self, done, func, args=[], kwargs={}, description=None): job = ParallelJob(func, done, self, args=args, kwargs=kwargs, description=description) @@ -159,15 +159,15 @@ class JobManager(QAbstractTableModel): def kill_job(self, row, view): job = self.jobs[row] if isinstance(job, DeviceJob): - error_dialog(view, _('Cannot kill job'), + error_dialog(view, _('Cannot kill job'), _('Cannot kill jobs that communicate with the device')).exec_() return if job.has_run: - error_dialog(view, _('Cannot kill job'), + error_dialog(view, _('Cannot kill job'), _('Job has already run')).exec_() return if not job.is_running: - error_dialog(view, _('Cannot kill job'), + error_dialog(view, _('Cannot kill job'), _('Cannot kill waiting job')).exec_() return diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 755eef6a1e..3c1b669d78 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -1,6 +1,6 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import os, textwrap, traceback, time +import os, textwrap, traceback, time, re from datetime import timedelta, datetime from operator import attrgetter @@ -13,7 +13,7 @@ from PyQt4.QtGui import QTableView, QProgressDialog, QAbstractItemView, QColor, from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, QString, \ QCoreApplication, SIGNAL, QObject, QSize, QModelIndex -from calibre import preferred_encoding +from calibre import strftime from calibre.ptempfile import PersistentTemporaryFile from calibre.library.database import LibraryDatabase, text_to_tokens from calibre.gui2 import NONE, TableView, qstring_to_unicode, config @@ -100,7 +100,7 @@ class BooksModel(QAbstractTableModel): QAbstractTableModel.__init__(self, parent) self.db = None self.cols = ['title', 'authors', 'size', 'date', 'rating', 'publisher', 'tags', 'series'] - self.editable_cols = [0, 1, 4, 5, 6] + self.editable_cols = [0, 1, 4, 5, 6, 7] self.default_image = QImage(':/images/book.svg') self.sorted_on = (3, Qt.AscendingOrder) self.last_search = '' # The last search performed on this model @@ -128,7 +128,7 @@ class BooksModel(QAbstractTableModel): for row in rows: if self.cover_cache: id = self.db.id(row) - self.cover_cache.refresh(id) + self.cover_cache.refresh([id]) if row == current_row: self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), self.get_book_display_info(row)) @@ -168,6 +168,11 @@ class BooksModel(QAbstractTableModel): def search_tokens(self, text): return text_to_tokens(text) + + def books_added(self, num): + if num > 0: + self.beginInsertRows(QModelIndex(), 0, num-1) + self.endInsertRows() def search(self, text, refinement, reset=True): tokens, OR = self.search_tokens(text) @@ -201,9 +206,13 @@ class BooksModel(QAbstractTableModel): LibraryDatabase.sizeof_old_database(path) > 0 def columnCount(self, parent): + if parent and parent.isValid(): + return 0 return len(self.cols) def rowCount(self, parent): + if parent and parent.isValid(): + return 0 return self.db.rows() if self.db else 0 def count(self): @@ -226,6 +235,7 @@ class BooksModel(QAbstractTableModel): else: formats = _('None') data[_('Formats')] = formats + data[_('Path')] = self.db.abspath(idx) comments = self.db.comments(idx) if not comments: comments = _('None') @@ -248,7 +258,10 @@ class BooksModel(QAbstractTableModel): for i in range(1, k): ids.extend([idx-i, idx+i]) ids = ids + [i for i in range(l, r, 1) if i not in ids] - ids = [self.db.id(i) for i in ids] + try: + ids = [self.db.id(i) for i in ids] + except IndexError: + return self.cover_cache.set_cache(ids) def current_changed(self, current, previous, emit_signal=True): @@ -261,6 +274,8 @@ class BooksModel(QAbstractTableModel): return data def get_book_info(self, index): + if isinstance(index, int): + index = self.index(index, 0) data = self.current_changed(index, None, False) row = index.row() data[_('Title')] = self.db.title(row) @@ -311,11 +326,17 @@ class BooksModel(QAbstractTableModel): ans = [] for row in (row.row() for row in rows): format = None - for f in self.db.formats(row).split(','): - if f.lower() in formats: + fmts = self.db.formats(row) + if not fmts: + return [] + db_formats = set(fmts.lower().split(',')) + available_formats = set([f.lower() for f in formats]) + u = available_formats.intersection(db_formats) + for f in formats: + if f.lower() in u: format = f break - if format: + if format is not None: pt = PersistentTemporaryFile(suffix='.'+format) pt.write(self.db.format(row, format)) pt.flush() @@ -360,7 +381,7 @@ class BooksModel(QAbstractTableModel): elif col == 1: au = self.db.authors(row) if au: - au = au.split(',') + au = [a.strip().replace('|', ',') for a in au.split(',')] return QVariant("\n".join(au)) elif col == 2: size = self.db.max_size(row) @@ -370,7 +391,7 @@ class BooksModel(QAbstractTableModel): dt = self.db.timestamp(row) if dt: dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight) - return QVariant(dt.strftime(BooksView.TIME_FMT).decode(preferred_encoding, 'replace')) + return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple())) elif col == 4: r = self.db.rating(row) r = r/2 if r else 0 @@ -430,8 +451,19 @@ class BooksModel(QAbstractTableModel): if col == 4: val = 0 if val < 0 else 5 if val > 5 else val val *= 2 - column = self.cols[col] - self.db.set(row, column, val) + if col == 7: + pat = re.compile(r'\[(\d+)\]') + match = pat.search(val) + id = self.db.id(row) + if match is not None: + self.db.set_series_index(id, int(match.group(1))) + val = pat.sub('', val) + val = val.strip() + if val: + self.db.set_series(id, val) + else: + column = self.cols[col] + self.db.set(row, column, val) self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), \ index, index) if col == self.sorted_on[0]: @@ -559,17 +591,17 @@ class DeviceBooksModel(BooksModel): self.marked_for_deletion = {} - def mark_for_deletion(self, id, rows): - self.marked_for_deletion[id] = self.indices(rows) + def mark_for_deletion(self, job, rows): + self.marked_for_deletion[job] = self.indices(rows) for row in rows: indices = self.row_indices(row) self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), indices[0], indices[-1]) - def deletion_done(self, id, succeeded=True): - if not self.marked_for_deletion.has_key(id): + def deletion_done(self, job, succeeded=True): + if not self.marked_for_deletion.has_key(job): return - rows = self.marked_for_deletion.pop(id) + rows = self.marked_for_deletion.pop(job) for row in rows: if not succeeded: indices = self.row_indices(self.index(row, 0)) @@ -662,9 +694,13 @@ class DeviceBooksModel(BooksModel): self.reset() def columnCount(self, parent): + if parent and parent.isValid(): + return 0 return 5 def rowCount(self, parent): + if parent and parent.isValid(): + return 0 return len(self.map) def set_database(self, db): @@ -690,7 +726,7 @@ class DeviceBooksModel(BooksModel): dt = item.datetime dt = datetime(*dt[0:6]) dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight) - data[_('Timestamp')] = dt.strftime('%a %b %d %H:%M:%S %Y') + data[_('Timestamp')] = strftime('%a %b %d %H:%M:%S %Y', dt.timetuple()) data[_('Tags')] = ', '.join(item.tags) self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data) @@ -731,7 +767,7 @@ class DeviceBooksModel(BooksModel): dt = self.db[self.map[row]].datetime dt = datetime(*dt[0:6]) dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight) - return QVariant(dt.strftime(BooksView.TIME_FMT)) + return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple())) elif col == 4: tags = self.db[self.map[row]].tags if tags: @@ -841,6 +877,13 @@ class SearchBox(QLineEdit): self.prev_search = text self.emit(SIGNAL('search(PyQt_PyObject, PyQt_PyObject)'), text, refinement) + def search_from_tokens(self, tokens, all): + ans = u' '.join([u'%s:%s'%x for x in tokens]) + if not all: + ans = '[' + ans + ']' + self.set_search_string(ans) + + def set_search_string(self, txt): self.normalize_state() self.setText(txt) diff --git a/src/calibre/gui2/lrf_renderer/document.py b/src/calibre/gui2/lrf_renderer/document.py index 5bc72b3630..691e1481ee 100644 --- a/src/calibre/gui2/lrf_renderer/document.py +++ b/src/calibre/gui2/lrf_renderer/document.py @@ -108,6 +108,7 @@ class _Canvas(QGraphicsRectItem): line = block.peek() y += block.bs.topskip block_consumed = False + line.height = min(line.height, self.max_y-block.bs.topskip) # LRF files from TOR have Plot elements with their height set to 800 while y + line.height <= self.max_y: block.commit() if isinstance(line, QGraphicsItem): diff --git a/src/calibre/gui2/lrf_renderer/text.py b/src/calibre/gui2/lrf_renderer/text.py index cc0da9e5ad..4db7d505d7 100644 --- a/src/calibre/gui2/lrf_renderer/text.py +++ b/src/calibre/gui2/lrf_renderer/text.py @@ -450,7 +450,7 @@ class Line(QGraphicsItem): if self.current_link is not None: self.end_link() - # We justify is line is small and it doesn't have links in it + # We justify if line is small and it doesn't have links in it # If it has links, justification would cause the boundingrect of the link to # be too small if self.current_width >= 0.85 * self.line_length and len(self.links) == 0: diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index a8e9dca223..90fe20f0a3 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1,11 +1,11 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import os, sys, textwrap, collections, traceback, time +import os, sys, textwrap, collections, traceback, time, re from xml.parsers.expat import ExpatError from functools import partial from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, QUrl from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox, \ - QToolButton, QDialog, QDesktopServices + QToolButton, QDialog, QDesktopServices, QFileDialog from PyQt4.QtSvg import QSvgRenderer from calibre import __version__, __appname__, islinux, sanitize_file_name, \ @@ -34,20 +34,20 @@ from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog from calibre.gui2.dialogs.jobs import JobsDialog from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog -from calibre.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog +from calibre.gui2.tools import convert_single_ebook, convert_bulk_ebooks, set_conversion_defaults, fetch_news from calibre.gui2.dialogs.config import ConfigDialog from calibre.gui2.dialogs.search import SearchDialog from calibre.gui2.dialogs.user_profiles import UserProfiles -import calibre.gui2.dialogs.comicconf as ComicConf from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.gui2.dialogs.book_info import BookInfo from calibre.ebooks.metadata.meta import set_metadata from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.html import gui_main as html2oeb from calibre.ebooks import BOOK_EXTENSIONS -from calibre.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS from calibre.library.database2 import LibraryDatabase2, CoverCache from calibre.parallel import JobKilled from calibre.utils.filenames import ascii_filename +from calibre.gui2.widgets import WarningDialog class Main(MainWindow, Ui_MainWindow): @@ -122,13 +122,13 @@ class Main(MainWindow, Ui_MainWindow): sm.addAction(_('Send to storage card by default')) sm.actions()[-1].setCheckable(True) def default_sync(checked): - config.set('send_to_device_by_default', bool(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) - sm.actions()[-1].setChecked(config.get('send_to_device_by_default')) + sm.actions()[-1].setChecked(config.get('send_to_storage_card_by_default')) default_sync(sm.actions()[-1].isChecked()) self.sync_menu = sm # Needed md = QMenu() @@ -178,7 +178,7 @@ class Main(MainWindow, Ui_MainWindow): cm.addAction(_('Convert individually')) cm.addAction(_('Bulk convert')) cm.addSeparator() - cm.addAction(_('Set defaults for conversion to LRF')) + cm.addAction(_('Set defaults for conversion')) cm.addAction(_('Set defaults for conversion of comics')) self.action_convert.setMenu(cm) QObject.connect(cm.actions()[0], SIGNAL('triggered(bool)'), self.convert_single) @@ -214,7 +214,17 @@ class Main(MainWindow, Ui_MainWindow): self.show() self.stack.setCurrentIndex(0) - db = LibraryDatabase2(self.library_path) + try: + db = LibraryDatabase2(self.library_path) + except OSError, 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('~'))) + if not dir: + QCoreApplication.exit(1) + else: + self.library_path = dir + db = LibraryDatabase2(self.library_path) self.library_view.set_database(db) if self.olddb is not None: from PyQt4.QtGui import QProgressDialog @@ -223,10 +233,13 @@ class Main(MainWindow, Ui_MainWindow): pd.setCancelButton(None) pd.setWindowTitle(_('Migrating database')) pd.show() - db.migrate_old(self.olddb, pd) + number_of_books = db.migrate_old(self.olddb, pd) + self.olddb.close() + if number_of_books == 0: + os.remove(self.olddb.dbpath) self.olddb = None prefs['library_path'] = self.library_path - self.library_view.sortByColumn(3, Qt.DescendingOrder) + self.library_view.sortByColumn(*dynamic.get('sort_column', (3, Qt.DescendingOrder))) if not self.library_view.restore_column_widths(): self.library_view.resizeColumnsToContents() self.library_view.resizeRowsToContents() @@ -234,6 +247,16 @@ class Main(MainWindow, Ui_MainWindow): self.cover_cache = CoverCache(self.library_path) self.cover_cache.start() self.library_view.model().cover_cache = self.cover_cache + self.tags_view.setVisible(False) + self.match_all.setVisible(False) + self.match_any.setVisible(False) + self.popularity.setVisible(False) + self.tags_view.set_database(db, self.match_all, self.popularity) + self.connect(self.tags_view, SIGNAL('tags_marked(PyQt_PyObject, PyQt_PyObject)'), + self.search.search_from_tokens) + self.connect(self.status_bar.tag_view_button, SIGNAL('toggled(bool)'), self.toggle_tags_view) + self.connect(self.search, SIGNAL('search(PyQt_PyObject, PyQt_PyObject)'), + self.tags_view.model().reinit) ########################### Cover Flow ################################ self.cover_flow = None if CoverFlow is not None: @@ -273,6 +296,18 @@ class Main(MainWindow, Ui_MainWindow): self.status_bar.book_info.book_data.setMaximumHeight(1000) self.setMaximumHeight(available_height()) + def toggle_tags_view(self, show): + if show: + self.tags_view.setVisible(True) + self.match_all.setVisible(True) + self.match_any.setVisible(True) + self.popularity.setVisible(True) + self.tags_view.setFocus(Qt.OtherFocusReason) + else: + self.tags_view.setVisible(False) + self.match_all.setVisible(False) + self.match_any.setVisible(False) + self.popularity.setVisible(False) def sync_cf_to_listview(self, index, *args): if not hasattr(index, 'row') and self.library_view.currentIndex().row() != index: @@ -411,8 +446,8 @@ class Main(MainWindow, Ui_MainWindow): files = _('

Books with the same title as the following already exist in the database. Add them anyway?

    ') for mi, formats in duplicates: files += '
  • '+mi.title+'
  • \n' - d = question_dialog(self, _('Duplicates found!'), files+'

') - if d.exec_() == QMessageBox.Yes: + d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'

', self) + if d.exec_() == QDialog.Accepted: for mi, formats in duplicates: self.library_view.model().db.import_book(mi, formats ) @@ -459,39 +494,58 @@ class Main(MainWindow, Ui_MainWindow): if to_device: self.status_bar.showMessage(_('Uploading books to device.'), 2000) - def _add_books(self, paths, to_device): - on_card = False if self.stack.currentIndex() != 2 else True + def _add_books(self, paths, to_device, on_card=None): + if on_card is None: + on_card = self.stack.currentIndex() == 2 # Get format and metadata information formats, metadata, names, infos = [], [], [], [] for book in paths: format = os.path.splitext(book)[1] format = format[1:] if format else None stream = open(book, 'rb') - mi = get_metadata(stream, stream_type=format, use_libprs_metadata=True) + try: + mi = get_metadata(stream, stream_type=format, use_libprs_metadata=True) + except: + mi = MetaInformation(None, None) if not mi.title: mi.title = os.path.splitext(os.path.basename(book))[0] + if not mi.authors: + mi.authors = [_('Unknown')] formats.append(format) metadata.append(mi) names.append(os.path.basename(book)) - if not mi.authors: - mi.authors = ['Unknown'] infos.append({'title':mi.title, 'authors':', '.join(mi.authors), 'cover':self.default_thumbnail, 'tags':[]}) if not to_device: - model = self.current_view().model() - duplicates = model.add_books(paths, formats, metadata) + model = self.library_view.model() + html_pat = re.compile(r'\.x{0,1}htm(l{0,1})\s*$', re.IGNORECASE) + paths = list(paths) + for i, path in enumerate(paths): + if html_pat.search(path) is not None: + try: + paths[i] = html2oeb(path) + except: + traceback.print_exc() + continue + if paths[i] is None: + paths[i] = path + else: + formats[i] = 'zip' + duplicates, number_added = model.add_books(paths, formats, metadata) if duplicates: files = _('

Books with the same title as the following already exist in the database. Add them anyway?

    ') for mi in duplicates[2]: files += '
  • '+mi.title+'
  • \n' - d = question_dialog(self, _('Duplicates found!'), files+'

') - if d.exec_() == QMessageBox.Yes: - model.add_books(*duplicates, **dict(add_duplicates=True)) - model.resort() - model.research() + d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'

', parent=self) + if d.exec_() == QDialog.Accepted: + num = model.add_books(*duplicates, **dict(add_duplicates=True))[1] + number_added += num + #self.library_view.sortByColumn(3, Qt.DescendingOrder) + #model.research() + model.books_added(number_added) else: - self.upload_books(paths, names, infos, on_card=on_card) + self.upload_books(paths, list(map(sanitize_file_name, names)), infos, on_card=on_card) def upload_books(self, files, names, metadata, on_card=False, memory=None): ''' @@ -557,9 +611,9 @@ class Main(MainWindow, Ui_MainWindow): else: view = self.memory_view if self.stack.currentIndex() == 1 else self.card_view paths = view.model().paths(rows) - id = self.remove_paths(paths) - self.delete_memory[id] = (paths, view.model()) - view.model().mark_for_deletion(id, rows) + job = self.remove_paths(paths) + self.delete_memory[job] = (paths, view.model()) + view.model().mark_for_deletion(job, rows) self.status_bar.showMessage(_('Deleting books from device.'), 1000) def remove_paths(self, paths): @@ -570,7 +624,7 @@ class Main(MainWindow, Ui_MainWindow): Called once deletion is done on the device ''' for view in (self.memory_view, self.card_view): - view.model().deletion_done(id, bool(job.exception)) + view.model().deletion_done(job, bool(job.exception)) if job.exception is not None: self.device_job_exception(job) return @@ -743,29 +797,32 @@ class Main(MainWindow, Ui_MainWindow): self.news_menu.set_custom_feeds(feeds) def fetch_news(self, data): - pt = PersistentTemporaryFile(suffix='_feeds2lrf.lrf') - pt.close() - args = ['feeds2lrf', '--output', pt.name, '--debug'] - if data['username']: - args.extend(['--username', data['username']]) - if data['password']: - args.extend(['--password', data['password']]) - args.append(data['script'] if data['script'] else data['title']) - job = self.job_manager.run_job(Dispatcher(self.news_fetched), 'feeds2lrf', args=[args], - description=_('Fetch news from ')+data['title']) - self.conversion_jobs[job] = (pt, 'lrf') + func, args, desc, fmt, temp_files = fetch_news(data) + self.status_bar.showMessage(_('Fetching news from ')+data['title'], 2000) + job = self.job_manager.run_job(Dispatcher(self.news_fetched), func, args=args, + description=desc) + self.conversion_jobs[job] = (temp_files, fmt) self.status_bar.showMessage(_('Fetching news from ')+data['title'], 2000) def news_fetched(self, job): - pt, fmt = self.conversion_jobs.pop(job) + temp_files, fmt = self.conversion_jobs.pop(job) + pt = temp_files[0] if job.exception is not None: self.job_exception(job) return - to_device = self.device_connected and fmt in self.device_manager.device_class.FORMATS - self._add_books([pt.name], to_device) + to_device = self.device_connected and fmt.lower() in self.device_manager.device_class.FORMATS + self._add_books([pt.name], to_device, + on_card=config.get('send_to_storage_card_by_default') and self.device_connected and bool(self.device_manager.device.card_prefix())) if to_device: self.status_bar.showMessage(_('News fetched. Uploading to device.'), 2000) self.persistent_files.append(pt) + try: + if not to_device: + for f in temp_files: + if os.path.exists(f.name): + os.remove(f.name) + except: + pass ############################################################################ @@ -789,189 +846,60 @@ class Main(MainWindow, Ui_MainWindow): others.append(r) return comics, others - def convert_bulk_others(self, rows): - d = LRFBulkDialog(self) - d.exec_() - if d.result() != QDialog.Accepted: - return - bad_rows = [] - - self.status_bar.showMessage(_('Starting Bulk conversion of %d books')%len(rows), 2000) - if rows and hasattr(rows[0], 'row'): - rows = [r.row() for r in rows] - for i, row in enumerate(rows): - cmdline = list(d.cmdline) - mi = self.library_view.model().db.get_metadata(row) - if mi.title: - cmdline.extend(['--title', mi.title]) - if mi.authors: - cmdline.extend(['--author', ','.join(mi.authors)]) - if mi.publisher: - cmdline.extend(['--publisher', mi.publisher]) - if mi.comments: - cmdline.extend(['--comment', mi.comments]) - data = None - for fmt in LRF_PREFERRED_SOURCE_FORMATS: - try: - data = self.library_view.model().db.format(row, fmt.upper()) - break - except: - continue - if data is None: - bad_rows.append(row) - continue - pt = PersistentTemporaryFile('.'+fmt.lower()) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.lrf') - of.close() - cover = self.library_view.model().db.cover(row) - if cover: - cf = PersistentTemporaryFile('.jpeg') - cf.write(cover) - cf.close() - cmdline.extend(['--cover', cf.name]) - cmdline.extend(['-o', of.name]) - cmdline.append(pt.name) - job = self.job_manager.run_job(Dispatcher(self.book_converted), - 'any2lrf', args=[cmdline], - description=_('Convert book %d of %d (%s)')%(i+1, len(rows), repr(mi.title))) - - - self.conversion_jobs[job] = (d.cover_file, pt, of, d.output_format, - self.library_view.model().db.id(row)) - res = [] - for row in bad_rows: - title = self.library_view.model().db.title(row) - res.append('
  • %s
  • '%title) - if res: - msg = _('

    Could not convert %d of %d books, because no suitable source format was found.

      %s
    ')%(len(res), len(rows), '\n'.join(res)) - warning_dialog(self, _('Could not convert some books'), msg).exec_() - def convert_bulk(self, checked): - comics, others = self.get_books_for_conversion() - if others: - self.convert_bulk_others(others) - if comics: - opts = ComicConf.get_bulk_conversion_options(self) - if opts: - for i, row in enumerate(comics): - options = opts.copy() - mi = self.library_view.model().db.get_metadata(row) - if mi.title: - options.title = mi.title - if mi.authors: - opts.author = ','.join(mi.authors) - data = None - for fmt in ['cbz', 'cbr']: - try: - data = self.library_view.model().db.format(row, fmt.upper()) - break - except: - continue - - pt = PersistentTemporaryFile('.'+fmt.lower()) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.lrf') - of.close() - setattr(options, 'output', of.name) - options.verbose = 1 - args = [pt.name, options] - job = self.job_manager.run_job(Dispatcher(self.book_converted), - 'comic2lrf', args=args, - description=_('Convert comic %d of %d (%s)')%(i+1, len(comics), repr(options.title))) - self.conversion_jobs[job] = (None, pt, of, 'lrf', - self.library_view.model().db.id(row)) - - - def set_conversion_defaults(self, checked): - d = LRFSingleDialog(self, None, None) - d.exec_() + r = self.get_books_for_conversion() + if r is None: + return + comics, others = r - def set_comic_conversion_defaults(self, checked): - ComicConf.set_conversion_defaults(self) - - def convert_single_others(self, rows): - changed = False - for row in rows: - d = LRFSingleDialog(self, self.library_view.model().db, row) - if d.selected_format: - d.exec_() - if d.result() == QDialog.Accepted: - cmdline = d.cmdline - data = self.library_view.model().db.format(row, d.selected_format) - pt = PersistentTemporaryFile('.'+d.selected_format.lower()) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.lrf') - of.close() - cmdline.extend(['-o', of.name]) - cmdline.append(pt.name) - job = self.job_manager.run_job(Dispatcher(self.book_converted), - 'any2lrf', args=[cmdline], - description=_('Convert book: ')+d.title()) - - - self.conversion_jobs[job] = (d.cover_file, pt, of, d.output_format, d.id) - changed = True + jobs, changed = convert_bulk_ebooks(self, self.library_view.model().db, comics, others) + for func, args, desc, fmt, id, temp_files in jobs: + job = self.job_manager.run_job(Dispatcher(self.book_converted), + func, args=args, description=desc) + self.conversion_jobs[job] = (temp_files, fmt, id) + if changed: self.library_view.model().resort(reset=False) self.library_view.model().research() + + def set_conversion_defaults(self, checked): + set_conversion_defaults(False, self, self.library_view.model().db) + def set_comic_conversion_defaults(self, checked): + set_conversion_defaults(True, self, self.library_view.model().db) def convert_single(self, checked): - comics, others = self.get_books_for_conversion() - if others: - self.convert_single_others(others) - changed = False - db = self.library_view.model().db - for row in comics: - mi = db.get_metadata(row) - title = author = _('Unknown') - if mi.title: - title = mi.title - if mi.authors: - author = ','.join(mi.authors) - defaults = db.conversion_options(db.id(row), 'comic') - opts, defaults = ComicConf.get_conversion_options(self, defaults, title, author) - if defaults is not None: - db.set_conversion_options(db.id(row), 'comic', defaults) - if opts is None: continue - for fmt in ['cbz', 'cbr']: - try: - data = db.format(row, fmt.upper()) - break - except: - continue - pt = PersistentTemporaryFile('.'+fmt) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.lrf') - of.close() - opts.output = of.name - opts.verbose = 1 - args = [pt.name, opts] - changed = True + r = self.get_books_for_conversion() + if r is None: return + comics, others = r + jobs, changed = convert_single_ebook(self, self.library_view.model().db, comics, others) + for func, args, desc, fmt, id, temp_files in jobs: job = self.job_manager.run_job(Dispatcher(self.book_converted), - 'comic2lrf', args=args, - description=_('Convert comic: ')+opts.title) - self.conversion_jobs[job] = (None, pt, of, 'lrf', - self.library_view.model().db.id(row)) + func, args=args, description=desc) + self.conversion_jobs[job] = (temp_files, fmt, id) + if changed: self.library_view.model().resort(reset=False) self.library_view.model().research() def book_converted(self, job): - of, fmt, book_id = self.conversion_jobs.pop(job)[2:] - if job.exception is not None: - self.job_exception(job) - return - data = open(of.name, 'rb') - self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) - data.close() - self.status_bar.showMessage(job.description + (' completed'), 2000) + temp_files, fmt, book_id = self.conversion_jobs.pop(job) + try: + if job.exception is not None: + self.job_exception(job) + return + data = open(temp_files[-1].name, 'rb') + self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) + data.close() + self.status_bar.showMessage(job.description + (' completed'), 2000) + finally: + for f in temp_files: + try: + if os.path.exists(f.name): + os.remove(f.name) + except: + pass #############################View book###################################### @@ -1086,16 +1014,22 @@ class Main(MainWindow, Ui_MainWindow): self.library_view.set_visible_columns(d.final_columns) self.tool_bar.setIconSize(config['toolbar_icon_size']) self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon if config['show_text_in_toolbar'] else Qt.ToolButtonIconOnly) - + self.save_menu.actions()[2].setText(_('Save only %s format to disk')%config.get('save_to_disk_single_format').upper()) if self.library_path != d.database_location: try: newloc = d.database_location if not os.path.exists(os.path.join(newloc, 'metadata.db')): if os.access(self.library_path, os.R_OK): + from PyQt4.QtGui import QProgressDialog + pd = QProgressDialog('', '', 0, 100, self) + pd.setWindowModality(Qt.ApplicationModal) + pd.setCancelButton(None) + pd.setWindowTitle(_('Copying database')) + pd.show() self.status_bar.showMessage(_('Copying library to ')+newloc) self.setCursor(Qt.BusyCursor) self.library_view.setEnabled(False) - self.library_view.model().db.move_library_to(newloc) + self.library_view.model().db.move_library_to(newloc, pd) else: try: db = LibraryDatabase2(newloc) @@ -1134,8 +1068,7 @@ class Main(MainWindow, Ui_MainWindow): return index = self.library_view.currentIndex() if index.isValid(): - info = self.library_view.model().get_book_info(index) - BookInfo(self, info).show() + BookInfo(self, self.library_view, index).show() ############################################################################ @@ -1184,7 +1117,13 @@ class Main(MainWindow, Ui_MainWindow): self.device_error_dialog.show() def job_exception(self, job): - + try: + if job.exception[0] == 'DRMError': + error_dialog(self, _('Conversion Error'), + _('

    Could not convert: %s

    It is a DRMed book. You must first remove the DRM using 3rd party tools.')%job.description.split(':')[-1]).exec_() + return + except: + pass only_msg = getattr(job.exception, 'only_msg', False) try: print job.console_text() @@ -1207,6 +1146,12 @@ class Main(MainWindow, Ui_MainWindow): self.library_path = prefs['library_path'] self.olddb = None if self.library_path is None: # Need to migrate to new database layout + QMessageBox.information(self, 'Database format changed', + '''\ +

    calibre's book storage format has changed. Instead of storing book files in a database, the +files are now stored in a folder on your filesystem. You will now be asked to choose the folder +in which you want to store your books files. Any existing books will be automatically migrated. + ''') self.database_path = prefs['database_path'] if not os.access(os.path.dirname(self.database_path), os.W_OK): error_dialog(self, _('Database does not exist'), @@ -1222,7 +1167,6 @@ class Main(MainWindow, Ui_MainWindow): home = os.path.dirname(self.database_path) if not os.path.exists(home): home = os.getcwd() - from PyQt4.QtGui import QFileDialog dir = unicode(QFileDialog.getExistingDirectory(self, _('Choose a location for your ebook library.'), home)) if not dir: @@ -1243,6 +1187,7 @@ class Main(MainWindow, Ui_MainWindow): def write_settings(self): config.set('main_window_geometry', self.saveGeometry()) + dynamic.set('sort_column', self.library_view.model().sorted_on) self.library_view.write_settings() if self.device_connected: self.memory_view.write_settings() diff --git a/src/calibre/gui2/main.ui b/src/calibre/gui2/main.ui index a5f7c2ddcc..065b322b04 100644 --- a/src/calibre/gui2/main.ui +++ b/src/calibre/gui2/main.ui @@ -24,14 +24,6 @@ :/library:/library - - - 0 - 79 - 865 - 716 - - @@ -242,60 +234,95 @@ - 2 + 0 - - - 0 - 0 - 100 - 30 - - - + - - - - 100 - 10 - - - - true - - - true - - - false - - - QAbstractItemView::DragDrop - - - true - - - QAbstractItemView::SelectRows - - - false - - + + + + + + + Match any + + + false + + + + + + + Match all + + + true + + + + + + + Sort by &popularity + + + + + + + true + + + true + + + true + + + true + + + + + + + + + + 100 + 10 + + + + true + + + true + + + false + + + QAbstractItemView::DragDrop + + + true + + + QAbstractItemView::SelectRows + + + false + + + + - - - 0 - 0 - 100 - 30 - - @@ -331,14 +358,6 @@ - - - 0 - 0 - 857 - 552 - - @@ -378,14 +397,6 @@ - - - 0 - 0 - 865 - 79 - - 0 @@ -425,14 +436,6 @@ - - - 0 - 795 - 865 - 27 - - true @@ -564,6 +567,11 @@ QTableView

    library.h
    + + TagsView + QTreeView +
    tags.h
    +
    diff --git a/src/calibre/gui2/make.py b/src/calibre/gui2/make.py deleted file mode 100644 index fea040ca71..0000000000 --- a/src/calibre/gui2/make.py +++ /dev/null @@ -1,116 +0,0 @@ -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' -''' -Manage the PyQt build system pyrcc4, pylupdate4, lrelease and friends. -''' - -import sys, os, subprocess, cStringIO, compiler, re -from functools import partial - -from PyQt4.uic import compileUi - -check_call = partial(subprocess.check_call, shell=True) -sys.path.insert(1, os.path.abspath('..%s..'%os.sep)) - -from calibre import __appname__ -from calibre.path import path - -def find_forms(): - forms = [] - for root, dirs, files in os.walk('.'): - for name in files: - if name.endswith('.ui'): - forms.append(os.path.abspath(os.path.join(root, name))) - - return forms - -def form_to_compiled_form(form): - return form.rpartition('.')[0]+'_ui.py' - -def build_forms(forms): - for form in forms: - compiled_form = form_to_compiled_form(form) - if not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime: - print 'Compiling form', form - buf = cStringIO.StringIO() - compileUi(form, buf) - dat = buf.getvalue() - dat = dat.replace('__appname__', __appname__) - dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc') - dat = dat.replace('from library import', 'from calibre.gui2.library import') - dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import') - dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(? images.mtime: - print 'Compiling images...' - files = [] - for x in p.walk(): - if '.svn' in x or '.bzr' in x or x.isdir(): - continue - alias = ' alias="library"' if x == p/'library.png' else '' - files.append('%s'%(alias, x)) - qrc = '\n\n%s\n\n'%'\n'.join(files) - f = open('images.qrc', 'wb') - f.write(qrc) - f.close() - check_call(' '.join(['pyrcc4', '-o', images, 'images.qrc'])) - compiler.compileFile(images) - os.utime(images, None) - os.utime(images, None) - print 'Size of images:', '%.2f MB'%(path(images+'c').size/(1024*1024.)) - - -def build(forms): - build_forms(forms) - build_images() - -def clean(forms): - for form in forms: - compiled_form = form_to_compiled_form(form) - if os.path.exists(compiled_form): - print 'Removing compiled form', compiled_form - os.unlink(compiled_form) - print 'Removing compiled images' - os.unlink('images_rc.py') - os.unlink('images_rc.pyc') - -def main(args=sys.argv): - - if not os.getcwd().endswith('gui2'): - raise Exception('Must be run from the gui2 directory') - - forms = find_forms() - if len(args) == 1: - args.append('all') - - if args[1] == 'all': - build(forms) - elif args[1] == 'clean': - clean(forms) - elif args[1] == 'test': - build(forms) - print 'Running main.py' - subprocess.call('python main.py', shell=True) - else: - print 'Usage: %s [all|clean|test]'%(args[0]) - return 1 - - return 0 - -if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file diff --git a/src/calibre/gui2/status.py b/src/calibre/gui2/status.py index 1a322f7e31..e66bb197a9 100644 --- a/src/calibre/gui2/status.py +++ b/src/calibre/gui2/status.py @@ -1,10 +1,10 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import re +import re, collections from PyQt4.QtGui import QStatusBar, QMovie, QLabel, QFrame, QHBoxLayout, QPixmap, \ QVBoxLayout, QSizePolicy, QToolButton, QIcon -from PyQt4.QtCore import Qt, QSize, SIGNAL +from PyQt4.QtCore import Qt, QSize, SIGNAL, QCoreApplication from calibre import fit_image, preferred_encoding from calibre.gui2 import qstring_to_unicode @@ -47,6 +47,13 @@ class BookInfoDisplay(QFrame): def mouseReleaseEvent(self, ev): self.emit(SIGNAL('mr(int)'), 1) + + WEIGHTS = collections.defaultdict(lambda : 100) + WEIGHTS[_('Path')] = 0 + WEIGHTS[_('Formats')] = 1 + WEIGHTS[_('Comments')] = 2 + WEIGHTS[_('Series')] = 3 + WEIGHTS[_('Tags')] = 4 def __init__(self, clear_message): QFrame.__init__(self) @@ -73,8 +80,10 @@ class BookInfoDisplay(QFrame): rows = u'' self.book_data.setText('') - self.data = data - for key in data.keys(): + self.data = data.copy() + keys = data.keys() + keys.sort(cmp=lambda x, y: cmp(self.WEIGHTS[x], self.WEIGHTS[y])) + for key in keys: txt = data[key] #txt = '
    \n'.join(textwrap.wrap(txt, 120)) if isinstance(key, str): @@ -140,13 +149,28 @@ class CoverFlowButton(QToolButton): def disable(self, reason): self.setDisabled(True) self.setToolTip(_('

    Browsing books by their covers is disabled.
    Import of pictureflow module failed:
    ')+reason) + +class TagViewButton(QToolButton): + + def __init__(self, parent=None): + QToolButton.__init__(self, parent) + self.setIconSize(QSize(80, 80)) + self.setIcon(QIcon(':/images/tags.svg')) + self.setToolTip(_('Click to browse books by tags')) + self.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)) + self.setCheckable(True) + self.setChecked(False) + self.setAutoRaise(True) + class StatusBar(QStatusBar): def __init__(self, jobs_dialog): QStatusBar.__init__(self) self.movie_button = MovieButton(QMovie(':/images/jobs-animated.mng'), jobs_dialog) self.cover_flow_button = CoverFlowButton() + self.tag_view_button = TagViewButton() self.addPermanentWidget(self.cover_flow_button) + self.addPermanentWidget(self.tag_view_button) self.addPermanentWidget(self.movie_button) self.book_info = BookInfoDisplay(self.clearMessage) self.connect(self.book_info, SIGNAL('show_book_info()'), self.show_book_info) @@ -186,6 +210,7 @@ class StatusBar(QStatusBar): if self.movie_button.movie.state() == QMovie.Running: self.movie_button.movie.jumpToFrame(0) self.movie_button.movie.setPaused(True) + QCoreApplication.instance().alert(self, 5000) if __name__ == '__main__': # Used to create the animated status icon diff --git a/src/calibre/gui2/tags.py b/src/calibre/gui2/tags.py new file mode 100644 index 0000000000..d7d6dc62d9 --- /dev/null +++ b/src/calibre/gui2/tags.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Browsing book collection by tags. +''' +from PyQt4.Qt import QAbstractItemModel, Qt, QVariant, QTreeView, QModelIndex, \ + QFont, SIGNAL, QSize, QColor, QIcon +from calibre.gui2 import config +NONE = QVariant() + +class TagsView(QTreeView): + + def __init__(self, *args): + QTreeView.__init__(self, *args) + self.setUniformRowHeights(True) + self.setCursor(Qt.PointingHandCursor) + self.setIconSize(QSize(30, 30)) + + def set_database(self, db, match_all, popularity): + self._model = TagsModel(db) + self.popularity = popularity + self.match_all = match_all + self.setModel(self._model) + self.connect(self, SIGNAL('clicked(QModelIndex)'), self.toggle) + self.popularity.setChecked(config['sort_by_popularity']) + self.connect(self.popularity, SIGNAL('stateChanged(int)'), self.sort_changed) + + def sort_changed(self, state): + config.set('sort_by_popularity', state == Qt.Checked) + self.model().refresh() + + def toggle(self, index): + if self._model.toggle(index): + self.emit(SIGNAL('tags_marked(PyQt_PyObject, PyQt_PyObject)'), + self._model.tokens(), self.match_all.isChecked()) + +class TagsModel(QAbstractItemModel): + + categories = [_('Authors'), _('Series'), _('Formats'), _('Publishers'), _('Tags')] + row_map = {0: 'author', 1:'series', 2:'format', 3:'publisher', 4:'tag'} + + def __init__(self, db): + QAbstractItemModel.__init__(self) + self.db = db + self.ignore_next_search = False + self._data = {} + self.refresh() + self.bold_font = QFont() + self.bold_font.setBold(True) + self.bold_font = QVariant(self.bold_font) + self.status_map = [QColor(200,200,200, 0), QIcon(':/images/plus.svg'), QIcon(':/images/minus.svg')] + self.status_map = list(map(QVariant, self.status_map)) + self.cmap = [QIcon(':/images/user_profile.svg'), QIcon(':/images/series.svg'), QIcon(':/images/book.svg'), QIcon(':/images/publisher.png'), QIcon(':/images/tags.svg')] + self.cmap = list(map(QVariant, self.cmap)) + self.db.add_listener(self.database_changed) + + def database_changed(self, event, ids): + self.refresh() + + def refresh(self): + old_data = self._data + self._data = self.db.get_categories(config['sort_by_popularity']) + for key in old_data.keys(): + for tag in old_data[key]: + try: + index = self._data[key].index(tag) + if index > -1: + self._data[key][index].state = tag.state + except: + continue + self.reset() + + def reinit(self, *args, **kwargs): + if not self.ignore_next_search: + for category in self._data.values(): + for tag in category: + tag.state = 0 + self.reset() + self.ignore_next_search = False + + def toggle(self, index): + if index.parent().isValid(): + category = self.row_map[index.parent().row()] + tag = self._data[category][index.row()] + tag.state = (tag.state + 1)%3 + self.ignore_next_search = True + self.emit(SIGNAL('dataChanged(QModelIndex,QModelIndex)'), index, index) + return True + return False + + def tokens(self): + ans = [] + for key in self.row_map.values(): + for tag in self._data[key]: + if tag.state > 0: + if tag.state == 2: + tag = '!'+tag + ans.append((key, tag)) + return ans + + def index(self, row, col, parent=QModelIndex()): + if parent.isValid(): + if parent.parent().isValid(): # parent is a tag + return QModelIndex() + try: + category = self.row_map[parent.row()] + except KeyError: + return QModelIndex() + if col == 0 and row < len(self._data[category]): + return self.createIndex(row, col, parent.row()) + return QModelIndex() + if col == 0 and row < len(self.categories): + return self.createIndex(row, col, -1) + return QModelIndex() + + def parent(self, index): + if not index.isValid() or index.internalId() < 0: + return QModelIndex() + return self.createIndex(index.internalId(), 0, -1) + + def rowCount(self, parent): + if not parent or not parent.isValid(): + return len(self.categories) + if not parent.parent().isValid(): + return len(self._data[self.row_map[parent.row()]]) + return 0 + + def columnCount(self, parent): + return 1 + + def flags(self, index): + if not index.isValid(): + return Qt.NoItemFlags + return Qt.ItemIsEnabled + + def category_data(self, index, role): + if role == Qt.DisplayRole: + row = index.row() + return QVariant(self.categories[row]) + if role == Qt.FontRole: + return self.bold_font + if role == Qt.SizeHintRole: + return QVariant(QSize(100, 40)) + if role == Qt.DecorationRole: + return self.cmap[index.row()] + return NONE + + def tag_data(self, index, role): + category = self.row_map[index.parent().row()] + if role == Qt.DisplayRole: + return QVariant(self._data[category][index.row()].as_string()) + if role == Qt.DecorationRole: + return self.status_map[self._data[category][index.row()].state] + return NONE + + + def data(self, index, role): + if not index.parent().isValid(): + return self.category_data(index, role) + if not index.parent().parent().isValid(): + return self.tag_data(index, role) + return NONE diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py new file mode 100644 index 0000000000..68d90f5228 --- /dev/null +++ b/src/calibre/gui2/tools.py @@ -0,0 +1,380 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Logic for setting up conversion jobs +''' +import os +from PyQt4.Qt import QDialog + +from calibre.utils.config import prefs +from calibre.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog +from calibre.gui2.dialogs.epub import Config as EPUBConvert +import calibre.gui2.dialogs.comicconf as ComicConf +from calibre.gui2 import warning_dialog +from calibre.ptempfile import PersistentTemporaryFile +from calibre.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS +from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.epub.from_any import SOURCE_FORMATS as EPUB_PREFERRED_SOURCE_FORMATS + +def convert_single_epub(parent, db, comics, others): + changed = False + jobs = [] + for row in others: + temp_files = [] + d = EPUBConvert(parent, db, row) + if d.source_format is not None: + d.exec_() + if d.result() == QDialog.Accepted: + opts = d.opts + data = db.format(row, d.source_format) + pt = PersistentTemporaryFile('.'+d.source_format.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.epub') + of.close() + opts.output = of.name + opts.from_opf = d.opf_file.name + opts.verbose = 2 + args = [opts, pt.name] + if d.cover_file: + temp_files.append(d.cover_file) + opts.cover = d.cover_file.name + temp_files.extend([d.opf_file, pt, of]) + jobs.append(('any2epub', args, _('Convert book: ')+d.mi.title, + 'EPUB', db.id(row), temp_files)) + changed = True + + for row in comics: + mi = db.get_metadata(row) + title = author = _('Unknown') + if mi.title: + title = mi.title + if mi.authors: + author = ','.join(mi.authors) + defaults = db.conversion_options(db.id(row), 'comic') + opts, defaults = ComicConf.get_conversion_options(parent, defaults, title, author) + if defaults is not None: + db.set_conversion_options(db.id(row), 'comic', defaults) + if opts is None: continue + for fmt in ['cbz', 'cbr']: + try: + data = db.format(row, fmt.upper()) + break + except: + continue + pt = PersistentTemporaryFile('.'+fmt) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.epub') + of.close() + opts.output = of.name + opts.verbose = 2 + args = [pt.name, opts] + changed = True + jobs.append(('comic2epub', args, _('Convert comic: ')+opts.title, + 'EPUB', db.id(row), [pt, of])) + + return jobs, changed + + + +def convert_single_lrf(parent, db, comics, others): + changed = False + jobs = [] + for row in others: + temp_files = [] + d = LRFSingleDialog(parent, db, row) + if d.selected_format: + d.exec_() + if d.result() == QDialog.Accepted: + cmdline = d.cmdline + data = db.format(row, d.selected_format) + pt = PersistentTemporaryFile('.'+d.selected_format.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.lrf') + of.close() + cmdline.extend(['-o', of.name]) + cmdline.append(pt.name) + if d.cover_file: + temp_files.append(d.cover_file) + temp_files.extend([pt, of]) + jobs.append(('any2lrf', [cmdline], _('Convert book: ')+d.title(), + 'LRF', db.id(row), temp_files)) + changed = True + + for row in comics: + mi = db.get_metadata(row) + title = author = _('Unknown') + if mi.title: + title = mi.title + if mi.authors: + author = ','.join(mi.authors) + defaults = db.conversion_options(db.id(row), 'comic') + opts, defaults = ComicConf.get_conversion_options(parent, defaults, title, author) + if defaults is not None: + db.set_conversion_options(db.id(row), 'comic', defaults) + if opts is None: continue + for fmt in ['cbz', 'cbr']: + try: + data = db.format(row, fmt.upper()) + break + except: + continue + pt = PersistentTemporaryFile('.'+fmt) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.lrf') + of.close() + opts.output = of.name + opts.verbose = 1 + args = [pt.name, opts] + changed = True + jobs.append(('comic2lrf', args, _('Convert comic: ')+opts.title, + 'LRF', db.id(row), [pt, of])) + + return jobs, changed + +def convert_bulk_epub(parent, db, comics, others): + if others: + d = EPUBConvert(parent, db) + if d.exec_() != QDialog.Accepted: + others = [] + else: + opts = d.opts + opts.verbose = 2 + if comics: + comic_opts = ComicConf.get_bulk_conversion_options(parent) + if not comic_opts: + comics = [] + bad_rows = [] + jobs = [] + total = sum(map(len, (others, comics))) + if total == 0: + return + parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000) + + for i, row in enumerate(others+comics): + if row in others: + data = None + for fmt in EPUB_PREFERRED_SOURCE_FORMATS: + try: + data = db.format(row, fmt.upper()) + break + except: + continue + if data is None: + bad_rows.append(row) + continue + options = opts.copy() + mi = db.get_metadata(row) + opf = OPFCreator(os.getcwdu(), mi) + opf_file = PersistentTemporaryFile('.opf') + opf.render(opf_file) + opf_file.close() + pt = PersistentTemporaryFile('.'+fmt.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.epub') + of.close() + cover = db.cover(row) + cf = None + if cover: + cf = PersistentTemporaryFile('.jpeg') + cf.write(cover) + cf.close() + options.cover = cf.name + options.output = of.name + options.from_opf = opf_file.name + args = [options, pt.name] + desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) + temp_files = [cf] if cf is not None else [] + temp_files.extend([opf_file, pt, of]) + jobs.append(('any2epub', args, desc, 'EPUB', db.id(row), temp_files)) + else: + options = comic_opts.copy() + mi = db.get_metadata(row) + if mi.title: + options.title = mi.title + if mi.authors: + options.author = ','.join(mi.authors) + data = None + for fmt in ['cbz', 'cbr']: + try: + data = db.format(row, fmt.upper()) + if data: + break + except: + continue + + pt = PersistentTemporaryFile('.'+fmt.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.epub') + of.close() + setattr(options, 'output', of.name) + options.verbose = 1 + args = [pt.name, options] + desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) + jobs.append(('comic2epub', args, desc, 'EPUB', db.id(row), [pt, of])) + + if bad_rows: + res = [] + for row in bad_rows: + title = db.title(row) + res.append('

  • %s
  • '%title) + + msg = _('

    Could not convert %d of %d books, because no suitable source format was found.

      %s
    ')%(len(res), total, '\n'.join(res)) + warning_dialog(parent, _('Could not convert some books'), msg).exec_() + + return jobs, False + + +def convert_bulk_lrf(parent, db, comics, others): + if others: + d = LRFBulkDialog(parent) + if d.exec_() != QDialog.Accepted: + others = [] + if comics: + comic_opts = ComicConf.get_bulk_conversion_options(parent) + if not comic_opts: + comics = [] + bad_rows = [] + jobs = [] + total = sum(map(len, (others, comics))) + if total == 0: + return + parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000) + + for i, row in enumerate(others+comics): + if row in others: + cmdline = list(d.cmdline) + mi = db.get_metadata(row) + if mi.title: + cmdline.extend(['--title', mi.title]) + if mi.authors: + cmdline.extend(['--author', ','.join(mi.authors)]) + if mi.publisher: + cmdline.extend(['--publisher', mi.publisher]) + if mi.comments: + cmdline.extend(['--comment', mi.comments]) + data = None + for fmt in LRF_PREFERRED_SOURCE_FORMATS: + try: + data = db.format(row, fmt.upper()) + break + except: + continue + if data is None: + bad_rows.append(row) + continue + pt = PersistentTemporaryFile('.'+fmt.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.lrf') + of.close() + cover = db.cover(row) + cf = None + if cover: + cf = PersistentTemporaryFile('.jpeg') + cf.write(cover) + cf.close() + cmdline.extend(['--cover', cf.name]) + cmdline.extend(['-o', of.name]) + cmdline.append(pt.name) + desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) + temp_files = [cf] if cf is not None else [] + temp_files.extend([pt, of]) + jobs.append(('any2lrf', [cmdline], desc, 'LRF', db.id(row), temp_files)) + else: + options = comic_opts.copy() + mi = db.get_metadata(row) + if mi.title: + options.title = mi.title + if mi.authors: + options.author = ','.join(mi.authors) + data = None + for fmt in ['cbz', 'cbr']: + try: + data = db.format(row, fmt.upper()) + if data: + break + except: + continue + + pt = PersistentTemporaryFile('.'+fmt.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.lrf') + of.close() + setattr(options, 'output', of.name) + options.verbose = 1 + args = [pt.name, options] + desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) + jobs.append(('comic2lrf', args, desc, 'LRF', db.id(row), [pt, of])) + + if bad_rows: + res = [] + for row in bad_rows: + title = db.title(row) + res.append('
  • %s
  • '%title) + + msg = _('

    Could not convert %d of %d books, because no suitable source format was found.

      %s
    ')%(len(res), total, '\n'.join(res)) + warning_dialog(parent, _('Could not convert some books'), msg).exec_() + + return jobs, False + +def set_conversion_defaults_lrf(comic, parent, db): + if comic: + ComicConf.set_conversion_defaults(parent) + else: + LRFSingleDialog(parent, None, None).exec_() + +def set_conversion_defaults_epub(comic, parent, db): + if comic: + ComicConf.set_conversion_defaults(parent) + else: + d = EPUBConvert(parent, db) + d.setWindowTitle(_('Set conversion defaults')) + d.exec_() + + +def _fetch_news(data, fmt): + pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower())) + pt.close() + args = ['feeds2%s'%fmt.lower(), '--output', pt.name, '--debug'] + if data['username']: + args.extend(['--username', data['username']]) + if data['password']: + args.extend(['--password', data['password']]) + args.append(data['script'] if data['script'] else data['title']) + return 'feeds2'+fmt.lower(), [args], _('Fetch news from ')+data['title'], fmt.upper(), [pt] + + +def convert_single_ebook(*args): + fmt = prefs['output_format'].lower() + if fmt == 'lrf': + return convert_single_lrf(*args) + elif fmt == 'epub': + return convert_single_epub(*args) + +def convert_bulk_ebooks(*args): + fmt = prefs['output_format'].lower() + if fmt == 'lrf': + return convert_bulk_lrf(*args) + elif fmt == 'epub': + return convert_bulk_epub(*args) + +def set_conversion_defaults(comic, parent, db): + fmt = prefs['output_format'].lower() + if fmt == 'lrf': + return set_conversion_defaults_lrf(comic, parent, db) + elif fmt == 'epub': + return set_conversion_defaults_epub(comic, parent, db) + +def fetch_news(data): + fmt = prefs['output_format'].lower() + return _fetch_news(data, fmt) \ No newline at end of file diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index ad89a08cb6..5b3c2afe8f 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -3,10 +3,10 @@ __copyright__ = '2008, Kovid Goyal ' ''' Miscellaneous widgets used in the GUI ''' -import re, os +import re, os, traceback from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \ QListWidgetItem, QTextCharFormat, QApplication, \ - QSyntaxHighlighter, QCursor, QColor, QWidget, \ + QSyntaxHighlighter, QCursor, QColor, QWidget, QDialog, \ QAbstractItemDelegate, QPixmap, QStyle, QFontMetrics from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, SIGNAL, \ QObject, QRegExp, QString, QSettings @@ -19,8 +19,16 @@ from calibre import fit_image from calibre.utils.fontconfig import find_font_families from calibre.ebooks.metadata.meta import metadata_from_filename from calibre.utils.config import prefs +from calibre.gui2.dialogs.warning_ui import Ui_Dialog as Ui_WarningDialog - +class WarningDialog(QDialog, Ui_WarningDialog): + + def __init__(self, title, msg, details, parent=None): + QDialog.__init__(self, parent) + self.setupUi(self) + self.setWindowTitle(title) + self.msg.setText(msg) + self.details.setText(details) class FilenamePattern(QWidget, Ui_Form): @@ -246,7 +254,12 @@ class FontFamilyModel(QAbstractListModel): def __init__(self, *args): QAbstractListModel.__init__(self, *args) - self.families = find_font_families() + try: + self.families = find_font_families() + except: + self.families = [] + print 'WARNING: Could not load fonts' + traceback.print_exc() self.families.sort() self.families[:0] = ['None'] diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index 3d054a2b70..834229bf15 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -318,7 +318,7 @@ def do_show_metadata(db, id, as_opf): mi = OPFCreator(os.getcwd(), mi) mi.render(sys.stdout) else: - print mi + print unicode(mi).encode(preferred_encoding) def command_show_metadata(args, dbpath): parser = get_parser(_( diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index cf6b59d25e..4b2b515808 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -822,17 +822,18 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; ''' Rebuild self.data and self.cache. Filter results are lost. ''' - FIELDS = {'title' : 'sort', - 'authors': 'author_sort', - 'publisher': 'publisher', - 'size': 'size', - 'date': 'timestamp', - 'timestamp':'timestamp', - 'formats':'formats', - 'rating': 'rating', - 'tags':'tags', - 'series': 'series', - } + FIELDS = { + 'title' : 'sort', + 'authors' : 'author_sort', + 'publisher' : 'publisher', + 'size' : 'size', + 'date' : 'timestamp', + 'timestamp' : 'timestamp', + 'formats' : 'formats', + 'rating' : 'rating', + 'tags' : 'tags', + 'series' : 'series', + } field = FIELDS[sort_field] order = 'ASC' if not ascending: @@ -894,6 +895,11 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; def id(self, index): return self.data[index][0] + + def row(self, id): + for r, record in enumerate(self.data): + if record[0] == id: + return r def title(self, index, index_is_id=False): if not index_is_id: @@ -904,7 +910,10 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; return _('Unknown') def authors(self, index, index_is_id=False): - ''' Authors as a comma separated list or None''' + ''' + Authors as a comma separated list or None. + In the comma separated list, commas in author names are replaced by | symbols + ''' if not index_is_id: return self.data[index][2] try: @@ -970,9 +979,15 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; return ans[0] def series_index(self, index, index_is_id=False): + ans = None if not index_is_id: - return self.data[index][10] - return self.conn.execute('SELECT series_index FROM books WHERE id=?', (index,)).fetchone()[0] + ans = self.data[index][10] + else: + ans = self.conn.execute('SELECT series_index FROM books WHERE id=?', (index,)).fetchone()[0] + try: + return int(ans) + except: + return 1 def books_in_series(self, series_id): ''' @@ -1212,6 +1227,9 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; aid = self.conn.execute('INSERT INTO series(name) VALUES (?)', (series,)).lastrowid self.conn.execute('INSERT INTO books_series_link(book, series) VALUES (?,?)', (id, aid)) self.conn.commit() + row = self.row(id) + if row is not None: + self.data[row][9] = series def remove_unused_series(self): for id, in self.conn.execute('SELECT id FROM series').fetchall(): @@ -1220,8 +1238,12 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; self.conn.commit() def set_series_index(self, id, idx): + idx = int(idx) self.conn.execute('UPDATE books SET series_index=? WHERE id=?', (int(idx), id)) self.conn.commit() + row = self.row(id) + if row is not None: + self.data[row][10] = idx def set_rating(self, id, rating): rating = int(rating) @@ -1342,7 +1364,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; Convenience method to return metadata as a L{MetaInformation} object. ''' aum = self.authors(idx, index_is_id=index_is_id) - if aum: aum = aum.split(',') + if aum: aum = [a.strip().replace('|', ',') for a in aum.split(',')] mi = MetaInformation(self.title(idx, index_is_id=index_is_id), aum) mi.author_sort = self.author_sort(idx, index_is_id=index_is_id) mi.comments = self.comments(idx, index_is_id=index_is_id) @@ -1418,6 +1440,8 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; fmts = '' for fmt in fmts.split(','): data = self.format(idx, fmt, index_is_id=index_is_id) + if not data: + continue fname = name +'.'+fmt.lower() fname = sanitize_file_name(fname) f = open(os.path.join(base, fname), 'w+b') @@ -1492,7 +1516,6 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; def import_book_directory(self, dirpath): dirpath = os.path.abspath(dirpath) formats = [] - for path in os.listdir(dirpath): path = os.path.abspath(os.path.join(dirpath, path)) if os.path.isdir(path) or not os.access(path, os.R_OK): @@ -1507,6 +1530,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; if not formats: return + mi = metadata_from_formats(formats) if mi.title is None: return @@ -1537,8 +1561,12 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; for id in indices: try: data = self.format(id, format, index_is_id=True) + if not data: + failures.append((id, self.title(id, index_is_id=True))) + continue except: failures.append((id, self.title(id, index_is_id=True))) + continue title = self.title(id, index_is_id=True) au = self.authors(id, index_is_id=True) if not au: diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 7d287ebfcb..55966dcde5 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -6,7 +6,8 @@ __docformat__ = 'restructuredtext en' ''' The database used to store ebook metadata ''' -import os, re, sys, shutil, cStringIO, glob, collections +import os, re, sys, shutil, cStringIO, glob, collections, textwrap, \ + operator, itertools, functools, traceback import sqlite3 as sqlite from itertools import repeat @@ -15,6 +16,8 @@ from PyQt4.QtGui import QApplication, QPixmap, QImage __app = None from calibre.library.database import LibraryDatabase +from calibre.ebooks.metadata import string_to_authors +from calibre.constants import preferred_encoding copyfile = os.link if hasattr(os, 'link') else shutil.copyfile filesystem_encoding = sys.getfilesystemencoding() @@ -47,6 +50,7 @@ class CoverCache(QThread): self.load_queue_lock = QReadWriteLock(QReadWriteLock.Recursive) self.cache = {} self.cache_lock = QReadWriteLock() + self.id_map_stale = True self.keep_running = True def build_id_map(self): @@ -60,6 +64,7 @@ class CoverCache(QThread): except: continue self.id_map_lock.unlock() + self.id_map_stale = False def set_cache(self, ids): @@ -79,9 +84,9 @@ class CoverCache(QThread): def run(self): while self.keep_running: - if self.id_map is None: + if self.id_map is None or self.id_map_stale: self.build_id_map() - while True: + while True: # Load images from the load queue self.load_queue_lock.lockForWrite() try: id = self.load_queue.popleft() @@ -101,6 +106,8 @@ class CoverCache(QThread): self.id_map_lock.lockForRead() if id in self.id_map.keys(): path = self.id_map[id] + else: + self.id_map_stale = True self.id_map_lock.unlock() if path and os.access(path, os.R_OK): try: @@ -139,7 +146,7 @@ class CoverCache(QThread): self.cache_lock.unlock() self.load_queue_lock.lockForWrite() for id in ids: - self.load_queue.append_left(id) + self.load_queue.appendleft(id) self.load_queue_lock.unlock() class Concatenate(object): @@ -159,6 +166,176 @@ class Concatenate(object): return self.ans[:-len(self.sep)] return self.ans +class ResultCache(object): + + ''' + Stores sorted and filtered metadata in memory. + ''' + + METHOD_MAP = { + 'title' : 'title', + 'authors' : 'author_sort', + 'author' : 'author_sort', + 'publisher' : 'publisher', + 'size' : 'size', + 'date' : 'timestamp', + 'timestamp' : 'timestamp', + 'rating' : 'rating', + 'tags' : 'tags', + 'series' : 'series', + } + + def __init__(self): + self._map = self._map_filtered = self._data = [] + + def __getitem__(self, row): + return self._data[self._map_filtered[row]] + + def __len__(self): + return len(self._map_filtered) + + def __iter__(self): + for id in self._map_filtered: + yield self._data[id] + + def remove(self, id): + self._data[id] = None + if id in self._map: + self._map.remove(id) + if id in self._map_filtered: + self._map_filtered.remove(id) + + def set(self, row, col, val): + id = self._map_filtered[row] + self._data[id][col] = val + + def index(self, id, cache=False): + x = self._map if cache else self._map_filtered + return x.index(id) + + def row(self, id): + return self.index(id) + + def refresh_ids(self, conn, ids): + for id in ids: + self._data[id] = conn.execute('SELECT * from meta WHERE id=?', (id,)).fetchone() + return map(self.row, ids) + + def books_added(self, ids, conn): + if not ids: + return + self._data.extend(repeat(None, max(ids)-len(self._data)+2)) + for id in ids: + self._data[id] = conn.execute('SELECT * from meta WHERE id=?', (id,)).fetchone() + self._map[0:0] = ids + self._map_filtered[0:0] = ids + + def refresh(self, db, field, ascending): + field = field.lower() + method = getattr(self, 'sort_on_' + self.METHOD_MAP[field]) + # Fast mapping from sorted row numbers to ids + self._map = map(operator.itemgetter(0), method('ASC' if ascending else 'DESC', db)) # Preserves sort order + # Fast mapping from sorted, filtered row numbers to ids + # At the moment it is the same as self._map + self._map_filtered = list(self._map) + temp = db.conn.execute('SELECT * FROM meta').fetchall() + # Fast mapping from ids to data. + # Can be None for ids that dont exist (i.e. have been deleted) + self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else [] + for r in temp: + self._data[r[0]] = r + + def filter(self, filters, refilter=False, OR=False): + ''' + Filter data based on filters. All the filters must match for an item to + be accepted. Matching is case independent regexp matching. + @param filters: A list of SearchToken objects + @param refilter: If True filters are applied to the results of the previous + filtering. + @param OR: If True, keeps a match if any one of the filters matches. If False, + keeps a match only if all the filters match + ''' + if not refilter: + self._map_filtered = list(self._map) + if filters: + remove = [] + for id in self._map_filtered: + if OR: + keep = False + for token in filters: + if token.match(self._data[id]): + keep = True + break + if not keep: + remove.append(id) + else: + for token in filters: + if not token.match(self._data[id]): + remove.append(id) + break + for id in remove: + self._map_filtered.remove(id) + + def sort_on_title(self, order, db): + return db.conn.execute('SELECT id FROM books ORDER BY sort ' + order).fetchall() + + def sort_on_author_sort(self, order, db): + return db.conn.execute('SELECT id FROM books ORDER BY author_sort,sort ' + order).fetchall() + + def sort_on_timestamp(self, order, db): + return db.conn.execute('SELECT id FROM books ORDER BY id ' + order).fetchall() + + def sort_on_publisher(self, order, db): + no_publisher = db.conn.execute('SELECT id FROM books WHERE books.id NOT IN (SELECT book FROM books_publishers_link) ORDER BY books.sort').fetchall() + ans = [] + for r in db.conn.execute('SELECT id FROM publishers ORDER BY name '+order).fetchall(): + publishers_id = r[0] + ans += db.conn.execute('SELECT id FROM books WHERE books.id IN (SELECT book FROM books_publishers_link WHERE publisher=?) ORDER BY books.sort '+order, (publishers_id,)).fetchall() + ans = (no_publisher + ans) if order == 'ASC' else (ans + no_publisher) + return ans + + + def sort_on_size(self, order, db): + return db.conn.execute('SELECT id FROM meta ORDER BY size ' + order).fetchall() + + def sort_on_rating(self, order, db): + no_rating = db.conn.execute('SELECT id FROM books WHERE books.id NOT IN (SELECT book FROM books_ratings_link) ORDER BY books.sort').fetchall() + ans = [] + for r in db.conn.execute('SELECT id FROM ratings ORDER BY rating '+order).fetchall(): + ratings_id = r[0] + ans += db.conn.execute('SELECT id FROM books WHERE books.id IN (SELECT book FROM books_ratings_link WHERE rating=?) ORDER BY books.sort', (ratings_id,)).fetchall() + ans = (no_rating + ans) if order == 'ASC' else (ans + no_rating) + return ans + + + def sort_on_series(self, order, db): + no_series = db.conn.execute('SELECT id FROM books WHERE books.id NOT IN (SELECT book FROM books_series_link) ORDER BY books.sort').fetchall() + ans = [] + for r in db.conn.execute('SELECT id FROM series ORDER BY name '+order).fetchall(): + series_id = r[0] + ans += db.conn.execute('SELECT id FROM books WHERE books.id IN (SELECT book FROM books_series_link WHERE series=?) ORDER BY books.series_index,books.id '+order, (series_id,)).fetchall() + ans = (no_series + ans) if order == 'ASC' else (ans + no_series) + return ans + + + def sort_on_tags(self, order, db): + no_tags = db.conn.execute('SELECT id FROM books WHERE books.id NOT IN (SELECT book FROM books_tags_link) ORDER BY books.sort').fetchall() + ans = [] + for r in db.conn.execute('SELECT id FROM tags ORDER BY name '+order).fetchall(): + tag_id = r[0] + ans += db.conn.execute('SELECT id FROM books WHERE books.id IN (SELECT book FROM books_tags_link WHERE tag=?) ORDER BY books.sort '+order, (tag_id,)).fetchall() + ans = (no_tags + ans) if order == 'ASC' else (ans + no_tags) + return ans + +class Tag(unicode): + + def __init__(self, name): + unicode.__init__(self, name) + self.count = 0 + self.state = 0 + + def as_string(self): + return u'[%d] %s'%(self.count, self) class LibraryDatabase2(LibraryDatabase): ''' @@ -204,26 +381,105 @@ class LibraryDatabase2(LibraryDatabase): def __init__(self, library_path, row_factory=False): if not os.path.exists(library_path): os.makedirs(library_path) + self.listeners = set([]) self.library_path = os.path.abspath(library_path) self.row_factory = row_factory self.dbpath = os.path.join(library_path, 'metadata.db') if isinstance(self.dbpath, unicode): self.dbpath = self.dbpath.encode(filesystem_encoding) self.connect() + # Upgrade database + while True: + meth = getattr(self, 'upgrade_version_%d'%self.user_version, None) + if meth is None: + break + else: + print 'Upgrading database to version %d...'%(self.user_version+1) + meth() + self.conn.commit() + self.user_version += 1 + self.data = ResultCache() + self.filter = self.data.filter + self.refresh = functools.partial(self.data.refresh, self) + self.index = self.data.index + self.refresh_ids = functools.partial(self.data.refresh_ids, self.conn) + self.row = self.data.row def initialize_database(self): from calibre.resources import metadata_sqlite self.conn.executescript(metadata_sqlite) self.user_version = 1 + + def upgrade_version_1(self): + ''' + Normalize indices. + ''' + self.conn.executescript(textwrap.dedent('''\ + DROP INDEX authors_idx; + CREATE INDEX authors_idx ON books (author_sort COLLATE NOCASE, sort COLLATE NOCASE); + DROP INDEX series_idx; + CREATE INDEX series_idx ON series (name COLLATE NOCASE); + CREATE INDEX series_sort_idx ON books (series_index, id); + ''')) + + def upgrade_version_2(self): + ''' Fix Foreign key constraints for deleting from link tables. ''' + script = textwrap.dedent('''\ + DROP TRIGGER fkc_delete_books_%(ltable)s_link; + CREATE TRIGGER fkc_delete_on_%(table)s + BEFORE DELETE ON %(table)s + BEGIN + SELECT CASE + WHEN (SELECT COUNT(id) FROM books_%(ltable)s_link WHERE %(ltable_col)s=OLD.id) > 0 + THEN RAISE(ABORT, 'Foreign key violation: %(table)s is still referenced') + END; + END; + DELETE FROM %(table)s WHERE (SELECT COUNT(id) FROM books_%(ltable)s_link WHERE %(ltable_col)s=%(table)s.id) < 1; + ''') + self.conn.executescript(script%dict(ltable='authors', table='authors', ltable_col='author')) + self.conn.executescript(script%dict(ltable='publishers', table='publishers', ltable_col='publisher')) + self.conn.executescript(script%dict(ltable='tags', table='tags', ltable_col='tag')) + self.conn.executescript(script%dict(ltable='series', table='series', ltable_col='series')) def path(self, index, index_is_id=False): 'Return the relative path to the directory containing this books files as a unicode string.' - id = index if index_is_id else self.id() + id = index if index_is_id else self.id(index) path = self.conn.execute('SELECT path FROM books WHERE id=?', (id,)).fetchone()[0].replace('/', os.sep) return path + + def abspath(self, index, index_is_id=False): + 'Return the absolute path to the directory containing this books files as a unicode string.' + path = os.path.join(self.library_path, self.path(index, index_is_id=index_is_id)) + if not os.path.exists(path): + os.makedirs(path) + return path + def construct_path_name(self, id): + ''' + Construct the directory name for this book based on its metadata. + ''' + authors = self.authors(id, index_is_id=True) + if not authors: + authors = _('Unknown') + author = sanitize_file_name(authors.split(',')[0][:self.PATH_LIMIT]).decode(filesystem_encoding) + title = sanitize_file_name(self.title(id, index_is_id=True)[:self.PATH_LIMIT]).decode(filesystem_encoding) + path = author + '/' + title + ' (%d)'%id + return path + + def construct_file_name(self, id): + ''' + Construct the file name for this book based on its metadata. + ''' + authors = self.authors(id, index_is_id=True) + if not authors: + authors = _('Unknown') + author = sanitize_file_name(authors.split(',')[0][:self.PATH_LIMIT]).decode(filesystem_encoding) + title = sanitize_file_name(self.title(id, index_is_id=True)[:self.PATH_LIMIT]).decode(filesystem_encoding) + name = title + ' - ' + author + return name + def set_path(self, index, index_is_id=False): ''' Set the path to the directory containing this books files based on its @@ -231,27 +487,64 @@ class LibraryDatabase2(LibraryDatabase): are copied and it is deleted. ''' id = index if index_is_id else self.id(index) - authors = self.authors(id, index_is_id=True) - if not authors: - authors = _('Unknown') - author = sanitize_file_name(authors.split(',')[0][:self.PATH_LIMIT]).decode(filesystem_encoding) - title = sanitize_file_name(self.title(id, index_is_id=True)[:self.PATH_LIMIT]).decode(filesystem_encoding) - path = author + '/' + title + ' (%d)'%id + path = self.construct_path_name(id) current_path = self.path(id, index_is_id=True).replace(os.sep, '/') - if path == current_path: + formats = self.formats(id, index_is_id=True) + formats = formats.split(',') if formats else [] + # Check if the metadata used to construct paths has changed + fname = self.construct_file_name(id) + changed = False + for format in formats: + name = self.conn.execute('SELECT name FROM data WHERE book=? AND format=?', (id, format)).fetchone()[0] + if name and name != fname: + changed = True + break + if path == current_path and not changed: return + tpath = os.path.join(self.library_path, *path.split('/')) if not os.path.exists(tpath): os.makedirs(tpath) spath = os.path.join(self.library_path, *current_path.split('/')) - if current_path and os.path.exists(spath): - for f in os.listdir(spath): - copyfile(os.path.join(spath, f), os.path.join(tpath, f)) + + if current_path and os.path.exists(spath): # Migrate existing files + cdata = self.cover(id, index_is_id=True) + if cdata is not None: + open(os.path.join(tpath, 'cover.jpg'), 'wb').write(cdata) + for format in formats: + # Get data as string (can't use file as source and target files may be the same) + f = self.format(id, format, index_is_id=True, as_file=False) + if not f: + continue + stream = cStringIO.StringIO(f) + self.add_format(id, format, stream, index_is_id=True, path=tpath) self.conn.execute('UPDATE books SET path=? WHERE id=?', (path, id)) self.conn.commit() + # Delete not needed directories + norm = lambda x : os.path.abspath(os.path.normcase(x)) if current_path and os.path.exists(spath): - shutil.rmtree(spath) + if norm(spath) != norm(tpath): + shutil.rmtree(spath) + parent = os.path.dirname(spath) + if len(os.listdir(parent)) == 0: + shutil.rmtree(parent) + def add_listener(self, listener): + ''' + Add a listener. Will be called on change events with two arguments. + Event name and list of affected ids. + ''' + self.listeners.add(listener) + + def notify(self, event, ids=[]): + 'Notify all listeners' + for listener in self.listeners: + try: + listener(event, ids) + except: + traceback.print_exc() + continue + def cover(self, index, index_is_id=False, as_file=False, as_image=False): ''' Return the cover image as a bytestring (in JPEG format) or None. @@ -288,13 +581,32 @@ class LibraryDatabase2(LibraryDatabase): p.loadFromData(data) p.save(path) - def format(self, index, format, index_is_id=False, as_file=False, mode='r+b'): - ''' - Return the ebook format as a bytestring or `None` if the format doesn't exist, - or we don't have permission to write to the ebook file. - - `as_file`: If True the ebook format is returned as a file object opened in `mode` - ''' + def all_formats(self): + formats = self.conn.execute('SELECT format from data').fetchall() + if not formats: + return set([]) + return set([f[0] for f in formats]) + + def formats(self, index, index_is_id=False): + ''' Return available formats as a comma separated list or None if there are no available formats ''' + id = index if index_is_id else self.id(index) + path = os.path.join(self.library_path, self.path(id, index_is_id=True)) + try: + formats = self.conn.execute('SELECT format FROM data WHERE book=?', (id,)).fetchall() + name = self.conn.execute('SELECT name FROM data WHERE book=?', (id,)).fetchone()[0] + formats = map(lambda x:x[0], formats) + except: + return None + ans = [] + for format in formats: + _format = ('.' + format.lower()) if format else '' + if os.access(os.path.join(path, name+_format), os.R_OK|os.W_OK): + ans.append(format) + return ','.join(ans) + + + def format_abspath(self, index, format, index_is_id=False): + 'Return absolute path to the ebook file of format `format`' id = index if index_is_id else self.id(index) path = os.path.join(self.library_path, self.path(id, index_is_id=True)) name = self.conn.execute('SELECT name FROM data WHERE book=? AND format=?', (id, format)).fetchone()[0] @@ -302,87 +614,180 @@ class LibraryDatabase2(LibraryDatabase): format = ('.' + format.lower()) if format else '' path = os.path.join(path, name+format) if os.access(path, os.R_OK|os.W_OK): - f = open(path, mode) - return f if as_file else f.read() + return path + + def format(self, index, format, index_is_id=False, as_file=False, mode='r+b'): + ''' + Return the ebook format as a bytestring or `None` if the format doesn't exist, + or we don't have permission to write to the ebook file. - def add_format(self, index, format, stream, index_is_id=False): + `as_file`: If True the ebook format is returned as a file object opened in `mode` + ''' + path = self.format_abspath(index, format, index_is_id=index_is_id) + if path is not None: + f = open(path, mode) + return f if as_file else f.read() + self.remove_format(id, format, index_is_id=True) + + def add_format(self, index, format, stream, index_is_id=False, path=None): id = index if index_is_id else self.id(index) - authors = self.authors(id, index_is_id=True) - if not authors: - authors = _('Unknown') - path = os.path.join(self.library_path, self.path(id, index_is_id=True)) - author = sanitize_file_name(authors.split(',')[0][:self.PATH_LIMIT]).decode(filesystem_encoding) - title = sanitize_file_name(self.title(id, index_is_id=True)[:self.PATH_LIMIT]).decode(filesystem_encoding) + if path is None: + path = os.path.join(self.library_path, self.path(id, index_is_id=True)) name = self.conn.execute('SELECT name FROM data WHERE book=? AND format=?', (id, format)).fetchone() if name: self.conn.execute('DELETE FROM data WHERE book=? AND format=?', (id, format)) - name = title + ' - ' + author + name = self.construct_file_name(id) ext = ('.' + format.lower()) if format else '' - shutil.copyfileobj(stream, open(os.path.join(path, name+ext), 'wb')) + dest = os.path.join(path, name+ext) + pdir = os.path.dirname(dest) + if not os.path.exists(pdir): + os.makedirs(pdir) + with open(dest, 'wb') as f: + shutil.copyfileobj(stream, f) stream.seek(0, 2) size=stream.tell() self.conn.execute('INSERT INTO data (book,format,uncompressed_size,name) VALUES (?,?,?,?)', (id, format.upper(), size, name)) self.conn.commit() + self.notify('metadata', [id]) def delete_book(self, id): ''' - Removes book from self.cache, self.data and underlying database. + Removes book from the result cache and the underlying database. ''' - try: - self.cache.pop(self.index(id, cache=True)) - self.data.pop(self.index(id, cache=False)) - except TypeError: #If data and cache are the same object - pass + self.data.remove(id) path = os.path.join(self.library_path, self.path(id, True)) if os.path.exists(path): shutil.rmtree(path) + parent = os.path.dirname(path) + if len(os.listdir(parent)) == 0: + shutil.rmtree(parent) self.conn.execute('DELETE FROM books WHERE id=?', (id,)) self.conn.commit() + self.clean() + self.notify('delete', [id]) def remove_format(self, index, format, index_is_id=False): id = index if index_is_id else self.id(index) path = os.path.join(self.library_path, self.path(id, index_is_id=True)) - name = self.conn.execute('SELECT name FROM data WHERE book=? AND format=?', (id, format)).fetchone()[0] + name = self.conn.execute('SELECT name FROM data WHERE book=? AND format=?', (id, format)).fetchone() + name = name[0] if name else False if name: ext = ('.' + format.lower()) if format else '' path = os.path.join(path, name+ext) - if os.access(path, os.W_OK): - os.unlink(path) + try: + os.remove(path) + except: + pass self.conn.execute('DELETE FROM data WHERE book=? AND format=?', (id, format.upper())) self.conn.commit() + self.notify('metadata', [id]) + + def clean(self): + ''' + Remove orphaned entries. + ''' + st = 'DELETE FROM %(table)s WHERE (SELECT COUNT(id) FROM books_%(ltable)s_link WHERE %(ltable_col)s=%(table)s.id) < 1;' + self.conn.execute(st%dict(ltable='authors', table='authors', ltable_col='author')) + self.conn.execute(st%dict(ltable='publishers', table='publishers', ltable_col='publisher')) + self.conn.execute(st%dict(ltable='tags', table='tags', ltable_col='tag')) + self.conn.execute(st%dict(ltable='series', table='series', ltable_col='series')) + self.conn.commit() + + def get_categories(self, sort_on_count=False): + categories = {} + def get(name, category, field='name'): + ans = self.conn.execute('SELECT DISTINCT %s FROM %s'%(field, name)).fetchall() + ans = [x[0].strip() for x in ans] + try: + ans.remove('') + except ValueError: pass + categories[category] = list(map(Tag, ans)) + tags = categories[category] + if name != 'data': + for tag in tags: + id = self.conn.execute('SELECT id FROM %s WHERE %s=?'%(name, field), (tag,)).fetchone() + if id: + id = id[0] + tag.id = id + for tag in tags: + if tag.id is not None: + tag.count = self.conn.execute('SELECT COUNT(id) FROM books_%s_link WHERE %s=?'%(name, category), (tag.id,)).fetchone()[0] + else: + for tag in tags: + tag.count = self.conn.execute('SELECT COUNT(format) FROM data WHERE format=?', (tag,)).fetchone()[0] + tags.sort(reverse=sort_on_count, cmp=(lambda x,y:cmp(x.count,y.count)) if sort_on_count else cmp) + for x in (('authors', 'author'), ('tags', 'tag'), ('publishers', 'publisher'), + ('series', 'series')): + get(*x) + get('data', 'format', 'format') + return categories + + + def set(self, row, column, val): + ''' + Convenience method for setting the title, authors, publisher or rating + ''' + id = self.data[row][0] + col = {'title':1, 'authors':2, 'publisher':3, 'rating':4, 'tags':7}[column] + + self.data.set(row, col, val) + if column == 'authors': + val = string_to_authors(val) + self.set_authors(id, val, notify=False) + elif column == 'title': + self.set_title(id, val, notify=False) + elif column == 'publisher': + self.set_publisher(id, val, notify=False) + elif column == 'rating': + self.set_rating(id, val) + elif column == 'tags': + self.set_tags(id, val.split(','), append=False, notify=False) + self.data.refresh_ids(self.conn, [id]) + self.set_path(id, True) + self.notify('metadata', [id]) def set_metadata(self, id, mi): ''' Set metadata for the book `id` from the `MetaInformation` object `mi` ''' + if mi.title: + self.set_title(id, mi.title) if not mi.authors: - mi.authors = ['Unknown'] + mi.authors = [_('Unknown')] authors = [] for a in mi.authors: authors += a.split('&') - self.set_authors(id, authors) + self.set_authors(id, authors, notify=False) if mi.author_sort: self.set_author_sort(id, mi.author_sort) if mi.publisher: - self.set_publisher(id, mi.publisher) + self.set_publisher(id, mi.publisher, notify=False) if mi.rating: self.set_rating(id, mi.rating) if mi.series: - self.set_series(id, mi.series) + self.set_series(id, mi.series, notify=False) if mi.cover_data[1] is not None: self.set_cover(id, mi.cover_data[1]) + if mi.tags: + self.set_tags(id, mi.tags, notify=False) + if mi.comments: + self.set_comment(id, mi.comments) self.set_path(id, True) + self.notify('metadata', [id]) - def set_authors(self, id, authors): + def set_authors(self, id, authors, notify=True): ''' `authors`: A list of authors. ''' self.conn.execute('DELETE FROM books_authors_link WHERE book=?',(id,)) + self.conn.execute('DELETE FROM authors WHERE (SELECT COUNT(id) FROM books_authors_link WHERE author=authors.id) < 1') for a in authors: if not a: continue - a = a.strip() + a = a.strip().replace(',', '|') + if not isinstance(a, unicode): + a = a.decode(preferred_encoding, 'replace') author = self.conn.execute('SELECT id from authors WHERE name=?', (a,)).fetchone() if author: aid = author[0] @@ -395,20 +800,103 @@ class LibraryDatabase2(LibraryDatabase): except sqlite.IntegrityError: # Sometimes books specify the same author twice in their metadata pass self.set_path(id, True) + self.notify('metadata', [id]) - def set_title(self, id, title): + def set_title(self, id, title, notify=True): if not title: return + if not isinstance(title, unicode): + title = title.decode(preferred_encoding, 'replace') self.conn.execute('UPDATE books SET title=? WHERE id=?', (title, id)) self.set_path(id, True) + self.notify('metadata', [id]) + def set_publisher(self, id, publisher, notify=True): + self.conn.execute('DELETE FROM books_publishers_link WHERE book=?',(id,)) + self.conn.execute('DELETE FROM publishers WHERE (SELECT COUNT(id) FROM books_publishers_link WHERE publisher=publishers.id) < 1') + if publisher: + if not isinstance(publisher, unicode): + publisher = publisher.decode(preferred_encoding, 'replace') + pub = self.conn.execute('SELECT id from publishers WHERE name=?', (publisher,)).fetchone() + if pub: + aid = pub[0] + else: + aid = self.conn.execute('INSERT INTO publishers(name) VALUES (?)', (publisher,)).lastrowid + self.conn.execute('INSERT INTO books_publishers_link(book, publisher) VALUES (?,?)', (id, aid)) + self.conn.commit() + self.notify('metadata', [id]) + + def set_tags(self, id, tags, append=False, notify=True): + ''' + @param tags: list of strings + @param append: If True existing tags are not removed + ''' + if not append: + self.conn.execute('DELETE FROM books_tags_link WHERE book=?', (id,)) + self.conn.execute('DELETE FROM tags WHERE (SELECT COUNT(id) FROM books_tags_link WHERE tag=tags.id) < 1') + for tag in set(tags): + tag = tag.lower().strip() + if not tag: + continue + if not isinstance(tag, unicode): + tag = tag.decode(preferred_encoding, 'replace') + t = self.conn.execute('SELECT id FROM tags WHERE name=?', (tag,)).fetchone() + if t: + tid = t[0] + else: + tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid + + if not self.conn.execute('SELECT book FROM books_tags_link WHERE book=? AND tag=?', + (id, tid)).fetchone(): + self.conn.execute('INSERT INTO books_tags_link(book, tag) VALUES (?,?)', + (id, tid)) + self.conn.commit() + self.notify('metadata', [id]) + + + def set_series(self, id, series, notify=True): + self.conn.execute('DELETE FROM books_series_link WHERE book=?',(id,)) + self.conn.execute('DELETE FROM series WHERE (SELECT COUNT(id) FROM books_series_link WHERE series=series.id) < 1') + if series: + if not isinstance(series, unicode): + series = series.decode(preferred_encoding, 'replace') + s = self.conn.execute('SELECT id from series WHERE name=?', (series,)).fetchone() + if s: + aid = s[0] + else: + aid = self.conn.execute('INSERT INTO series(name) VALUES (?)', (series,)).lastrowid + self.conn.execute('INSERT INTO books_series_link(book, series) VALUES (?,?)', (id, aid)) + self.conn.commit() + try: + row = self.row(id) + if row is not None: + self.data.set(row, 9, series) + except ValueError: + pass + self.notify('metadata', [id]) + + def set_series_index(self, id, idx, notify=True): + if idx is None: + idx = 1 + idx = int(idx) + self.conn.execute('UPDATE books SET series_index=? WHERE id=?', (int(idx), id)) + self.conn.commit() + try: + row = self.row(id) + if row is not None: + self.data.set(row, 10, idx) + except ValueError: + pass + self.notify('metadata', [id]) + def add_books(self, paths, formats, metadata, uris=[], add_duplicates=True): ''' - Add a book to the database. self.data and self.cache are not updated. + Add a book to the database. The result cache is not updated. @param paths: List of paths to book files of file-like objects ''' formats, metadata, uris = iter(formats), iter(metadata), iter(uris) duplicates = [] + ids = [] for path in paths: mi = metadata.next() format = formats.next() @@ -424,6 +912,7 @@ class LibraryDatabase2(LibraryDatabase): obj = self.conn.execute('INSERT INTO books(title, uri, series_index, author_sort) VALUES (?, ?, ?, ?)', (mi.title, uri, series_index, aus)) id = obj.lastrowid + ids.append(id) self.set_path(id, True) self.conn.commit() self.set_metadata(id, mi) @@ -434,13 +923,15 @@ class LibraryDatabase2(LibraryDatabase): if not hasattr(path, 'read'): stream.close() self.conn.commit() + if ids: + self.data.books_added(ids, self.conn) if duplicates: paths = tuple(duplicate[0] for duplicate in duplicates) formats = tuple(duplicate[1] for duplicate in duplicates) metadata = tuple(duplicate[2] for duplicate in duplicates) uris = tuple(duplicate[3] for duplicate in duplicates) - return (paths, formats, metadata, uris) - return None + return (paths, formats, metadata, uris), len(ids) + return None, len(ids) def import_book(self, mi, formats): series_index = 1 if mi.series_index is None else mi.series_index @@ -457,12 +948,24 @@ class LibraryDatabase2(LibraryDatabase): stream = open(path, 'rb') self.add_format(id, ext, stream, index_is_id=True) self.conn.commit() - - def move_library_to(self, newloc): + self.data.books_added([id], self.conn) + self.notify('add', [id]) + + def move_library_to(self, newloc, progress=None): + header = _(u'

    Copying books to %s

    ')%newloc + books = self.conn.execute('SELECT id, path, title FROM books').fetchall() + if progress is not None: + progress.setValue(0) + progress.setLabelText(header) + QCoreApplication.processEvents() + progress.setAutoReset(False) + progress.setRange(0, len(books)) if not os.path.exists(newloc): os.makedirs(newloc) old_dirs = set([]) - for book in self.conn.execute('SELECT id, path FROM books').fetchall(): + for i, book in enumerate(books): + if progress is not None: + progress.setLabelText(header+_(u'Copying %s')%book[2]) path = book[1] if not path: continue @@ -471,8 +974,11 @@ class LibraryDatabase2(LibraryDatabase): tdir = os.path.join(newloc, dir) if os.path.exists(tdir): shutil.rmtree(tdir) - shutil.copytree(srcdir, tdir) + if os.path.exists(srcdir): + shutil.copytree(srcdir, tdir) old_dirs.add(srcdir) + if progress is not None: + progress.setValue(i+1) dbpath = os.path.join(newloc, os.path.basename(self.dbpath)) shutil.copyfile(self.dbpath, dbpath) @@ -486,6 +992,9 @@ class LibraryDatabase2(LibraryDatabase): shutil.rmtree(dir) except: pass + if progress is not None: + progress.reset() + progress.hide() def migrate_old(self, db, progress): @@ -494,7 +1003,9 @@ class LibraryDatabase2(LibraryDatabase): progress.setLabelText(header) QCoreApplication.processEvents() db.conn.row_factory = lambda cursor, row : tuple(row) + db.conn.text_factory = lambda x : unicode(x, 'utf-8', 'replace') books = db.conn.execute('SELECT id, title, sort, timestamp, uri, series_index, author_sort, isbn FROM books ORDER BY id ASC').fetchall() + progress.setAutoReset(False) progress.setRange(0, len(books)) for book in books: @@ -533,4 +1044,7 @@ books_series_link feeds self.conn.commit() progress.setLabelText(_('Compacting database')) self.vacuum() + progress.reset() + return len(books) + diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 8fbab59bcf..096f4ef3f9 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -21,10 +21,16 @@ entry_points = { 'rtf-meta = calibre.ebooks.metadata.rtf:main', 'pdf-meta = calibre.ebooks.metadata.pdf:main', 'lit-meta = calibre.ebooks.metadata.lit:main', + 'imp-meta = calibre.ebooks.metadata.imp:main', + 'rb-meta = calibre.ebooks.metadata.rb:main', 'opf-meta = calibre.ebooks.metadata.opf:main', + 'odt-meta = calibre.ebooks.metadata.odt:main', 'epub-meta = calibre.ebooks.metadata.epub:main', 'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main', 'html2lrf = calibre.ebooks.lrf.html.convert_from:main', + 'html2oeb = calibre.ebooks.html:main', + 'html2epub = calibre.ebooks.epub.from_html:main', + 'odt2oeb = calibre.ebooks.odt.to_oeb:main', 'markdown-calibre = calibre.ebooks.markdown.markdown:main', 'lit2lrf = calibre.ebooks.lrf.lit.convert_from:main', 'epub2lrf = calibre.ebooks.lrf.epub.convert_from:main', @@ -32,12 +38,14 @@ entry_points = { 'web2disk = calibre.web.fetch.simple:main', 'feeds2disk = calibre.web.feeds.main:main', 'feeds2lrf = calibre.ebooks.lrf.feeds.convert_from:main', + 'feeds2epub = calibre.ebooks.epub.from_feeds:main', 'web2lrf = calibre.ebooks.lrf.web.convert_from:main', 'pdf2lrf = calibre.ebooks.lrf.pdf.convert_from:main', 'mobi2lrf = calibre.ebooks.lrf.mobi.convert_from:main', 'fb22lrf = calibre.ebooks.lrf.fb2.convert_from:main', 'fb2-meta = calibre.ebooks.metadata.fb2:main', 'any2lrf = calibre.ebooks.lrf.any.convert_from:main', + 'any2epub = calibre.ebooks.epub.from_any:main', 'lrf2lrs = calibre.ebooks.lrf.lrfparser:main', 'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main', 'pdfreflow = calibre.ebooks.lrf.pdf.reflow:main', @@ -47,6 +55,7 @@ entry_points = { 'lrf2html = calibre.ebooks.lrf.html.convert_to:main', 'lit2oeb = calibre.ebooks.lit.reader:main', 'comic2lrf = calibre.ebooks.lrf.comic.convert_from:main', + 'comic2epub = calibre.ebooks.epub.from_comic:main', 'calibre-debug = calibre.debug:main', 'calibredb = calibre.library.cli:main', 'calibre-fontconfig = calibre.utils.fontconfig:main', @@ -167,7 +176,14 @@ def setup_completion(fatal_errors): from calibre.ebooks.lrf.feeds.convert_from import option_parser as feeds2lrf from calibre.ebooks.metadata.epub import option_parser as epub_meta from calibre.ebooks.lrf.comic.convert_from import option_parser as comicop - + from calibre.ebooks.epub.from_html import option_parser as html2epub + from calibre.ebooks.html import option_parser as html2oeb + from calibre.ebooks.odt.to_oeb import option_parser as odt2oeb + from calibre.ebooks.epub.from_feeds import option_parser as feeds2epub + from calibre.ebooks.epub.from_any import option_parser as any2epub + from calibre.ebooks.epub.from_comic import option_parser as comic2epub + any_formats = ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', + 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi', 'fb2', 'odt'] f = open_file('/etc/bash_completion.d/libprs500') f.close() os.remove(f.name) @@ -185,23 +201,30 @@ def setup_completion(fatal_errors): f.write(opts_and_exts('mobi2lrf', htmlop, ['mobi', 'prc'])) f.write(opts_and_exts('fb22lrf', htmlop, ['fb2'])) f.write(opts_and_exts('pdf2lrf', htmlop, ['pdf'])) - f.write(opts_and_exts('any2lrf', htmlop, - ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', - 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi', 'fb2'])) + f.write(opts_and_exts('any2lrf', htmlop, any_formats)) + f.write(opts_and_exts('any2lrf', any2epub, any_formats)) f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf'])) f.write(opts_and_exts('lrf-meta', metaop, ['lrf'])) f.write(opts_and_exts('rtf-meta', metaop, ['rtf'])) f.write(opts_and_exts('pdf-meta', metaop, ['pdf'])) f.write(opts_and_exts('lit-meta', metaop, ['lit'])) + f.write(opts_and_exts('imp-meta', metaop, ['imp'])) + f.write(opts_and_exts('rb-meta', metaop, ['rb'])) f.write(opts_and_exts('opf-meta', metaop, ['opf'])) + f.write(opts_and_exts('odt-meta', metaop, ['odt', 'ods', 'odf', 'odg', 'odp'])) f.write(opts_and_exts('epub-meta', epub_meta, ['epub'])) f.write(opts_and_exts('lrfviewer', lrfviewerop, ['lrf'])) f.write(opts_and_exts('pdfrelow', pdfhtmlop, ['pdf'])) f.write(opts_and_exts('mobi2oeb', mobioeb, ['mobi', 'prc'])) f.write(opts_and_exts('lit2oeb', lit2oeb, ['lit'])) f.write(opts_and_exts('comic2lrf', comicop, ['cbz', 'cbr'])) + f.write(opts_and_exts('comic2epub', comic2epub, ['cbz', 'cbr'])) f.write(opts_and_words('feeds2disk', feeds2disk, feed_titles)) f.write(opts_and_words('feeds2lrf', feeds2lrf, feed_titles)) + f.write(opts_and_words('feeds2lrf', feeds2epub, feed_titles)) + f.write(opts_and_exts('html2epub', html2epub, ['html', 'htm', 'xhtm', 'xhtml', 'opf'])) + f.write(opts_and_exts('html2oeb', html2oeb, ['html', 'htm', 'xhtm', 'xhtml'])) + f.write(opts_and_exts('odt2oeb', odt2oeb, ['odt'])) f.write(''' _prs500_ls() { @@ -277,6 +300,11 @@ complete -o nospace -F _prs500 prs500 ''') f.close() print 'done' + except TypeError, err: + if 'resolve_entities' in str(err): + print 'You need python-lxml >= 2.0.5 for calibre' + sys.exit(1) + raise except: if fatal_errors: raise @@ -371,7 +399,8 @@ def install_man_pages(fatal_errors): prog = src[:src.index('=')].strip() if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta', 'markdown-calibre', 'calibre-debug', 'fb2-meta', - 'calibre-fontconfig', 'calibre-parallel'): + 'calibre-fontconfig', 'calibre-parallel', + 'rb-meta', 'imp-meta'): continue help2man = ('help2man', prog, '--name', 'part of %s'%__appname__, @@ -421,6 +450,13 @@ def post_install(): if opts.save_manifest_to: open(opts.save_manifest_to, 'wb').write('\n'.join(manifest)+'\n') + + from calibre.utils.config import config_dir + if os.path.exists(config_dir): + os.chdir(config_dir) + for f in os.listdir('.'): + if os.stat(f).st_uid == 0: + os.unlink(f) VIEWER = '''\ diff --git a/src/calibre/linux_installer.py b/src/calibre/linux_installer.py index f494bd0b14..e07cdc192a 100644 --- a/src/calibre/linux_installer.py +++ b/src/calibre/linux_installer.py @@ -278,7 +278,7 @@ def download_tarball(): def main(args=sys.argv): defdir = '/opt/calibre' - destdir = raw_input('Enter the installation directory for calibre [%s]: '%defdir).strip() + destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip() if not destdir: destdir = defdir if os.path.exists(destdir): diff --git a/src/calibre/manual/custom.py b/src/calibre/manual/custom.py index 2098369fee..1b0a6334d7 100644 --- a/src/calibre/manual/custom.py +++ b/src/calibre/manual/custom.py @@ -58,7 +58,7 @@ CLI_CMD=r''' .. include:: ../global.rst || .. _$cmd: -|| +|| #def option(opt) :option:`${opt.get_opt_string() + ((', '+', '.join(opt._short_opts)) if opt._short_opts else '')}` #end @@ -68,7 +68,7 @@ $cmd .. code-block:: none || $cmdline -|| +|| #for line in usage #choose #when len(line) > 0 @@ -95,7 +95,7 @@ $desc #end #for opt in options ${option(opt)} - ${opt.help.replace('\n', ' ').replace('%default', str(opt.default)) if opt.help else ''} + ${opt.help.replace('\n', ' ').replace('*', '\\*').replace('%default', str(opt.default)) if opt.help else ''} || #end #end @@ -106,7 +106,7 @@ def cli_docs(app): info(bold('creating CLI documentation...')) documented_cmds = [] undocumented_cmds = [] - + for script in entry_points['console_scripts']: module = script[script.index('=')+1:script.index(':')].strip() cmd = script[:script.index('=')].strip() @@ -115,22 +115,22 @@ def cli_docs(app): documented_cmds.append((cmd, getattr(module, 'option_parser')())) else: undocumented_cmds.append(cmd) - + documented_cmds.sort(cmp=lambda x, y: cmp(x[0], y[0])) undocumented_cmds.sort() - + templ = TextTemplate(CLI_INDEX) - raw = templ.generate(documented_commands=documented_cmds, + raw = templ.generate(documented_commands=documented_cmds, undocumented_commands=undocumented_cmds).render() raw = raw.replace('||', '\n') if not os.path.exists('cli'): os.makedirs('cli') if not os.path.exists(os.path.join('cli', 'global.rst')): - os.link('global.rst', os.path.join('cli', 'global.rst')) + os.link('global.rst', os.path.join('cli', 'global.rst')) if not os.path.exists(os.path.join('cli', 'cli-index.rst')): info(bold('creating cli-index...')) open(os.path.join('cli', 'cli-index.rst'), 'wb').write(raw) - + templ = TextTemplate(CLI_CMD) for cmd, parser in documented_cmds: usage = [i for i in parser.usage.replace('%prog', cmd).splitlines()] @@ -140,18 +140,19 @@ def cli_docs(app): groups = [(None, None, parser.option_list)] for grp in parser.option_groups: groups.append((grp.title, grp.description, grp.option_list)) - + raw = templ.generate(cmd=cmd, cmdline=cmdline, usage=usage, groups=groups).render() raw = raw.replace('||', '\n').replace('<', '<').replace('>', '>') if not os.path.exists(os.path.join('cli', cmd+'.rst')): info(bold('creating docs for %s...'%cmd)) open(os.path.join('cli', cmd+'.rst'), 'wb').write(raw) + def auto_member(dirname, arguments, options, content, lineno, content_offset, block_text, state, state_machine): name = arguments[0] env = state.document.settings.env - + mod_cls, obj = rpartition(name, '.') if not mod_cls and hasattr(env, 'autodoc_current_class'): mod_cls = env.autodoc_current_class @@ -162,11 +163,11 @@ def auto_member(dirname, arguments, options, content, lineno, mod = env.autodoc_current_module if not mod: mod = env.currmodule - + module = __import__(mod, None, None, ['foo']) cls = getattr(module, cls) lines = inspect.getsourcelines(cls)[0] - + comment_lines = [] for i, line in enumerate(lines): if re.search(r'%s\s*=\s*\S+'%obj, line) and not line.strip().startswith('#:'): @@ -178,33 +179,32 @@ def auto_member(dirname, arguments, options, content, lineno, break comment_lines.reverse() docstring = '\n'.join(comment_lines) - + if module is not None and docstring is not None: docstring = docstring.decode(get_module_charset(mod)) - + result = ViewList() result.append('.. attribute:: %s.%s'%(cls.__name__, obj), '') result.append('', '') - + docstring = prepare_docstring(docstring) for i, line in enumerate(docstring): result.append(' ' + line, '' % name, i) - + result.append('', '') result.append(' **Default**: ``%s``'%repr(getattr(cls, obj, None)), '') result.append('', '') node = nodes.paragraph() state.nested_parse(result, content_offset, node) - - return node - - - + return list(node) + + + def setup(app): app.add_builder(CustomBuilder) app.add_directive('automember', auto_member, 1, (1, 0, 1)) app.connect('doctree-read', substitute) app.connect('builder-inited', cli_docs) - + diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index f8c4d744db..7438b5cde8 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -17,11 +17,43 @@ E-book Format Conversion What formats does |app| support conversion to/from? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -|app| supports the conversion of the following formats to LRF: HTML, LIT, MOBI, PRC, EPUB, CBR, CBZ, RTF, TXT, PDF and LRS. It also supports the conversion of LRF to LRS and HTML(forthcoming). Note that calibre does not support the conversion of DRMed ebooks. +|app| supports the conversion of the following formats: -What are the best formats to convert to LRF? ++----------------------------+------------------------------------------+ +| | **Output formats** | +| +------------------+-----------------------+ +| | EPUB | LRF | ++===================+========+==================+=======================+ +| | MOBI | ✔ | ✔ | +| | | | | +| | LIT | ✔ | ✔ | +| | | | | +| | PRC | ✔ | ✔ | +| | | | | +| | EPUB | ✔ | ✔ | +| | | | | +| | ODT | ✔ | ✔ | +| | | | | +| | HTML | ✔ | ✔ | +| | | | | +| **Input formats** | CBR | ✔ | ✔ | +| | | | | +| | CBZ | ✔ | ✔ | +| | | | | +| | RTF | ✔ | ✔ | +| | | | | +| | TXT | ✔ | ✔ | +| | | | | +| | PDF | ✔ | ✔ | +| | | | | +| | LRS | | ✔ | ++-------------------+--------+------------------+-----------------------+ + + + +What are the best source formats to convert? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In order of decreasing preference: LIT, MOBI, HTML, PRC, RTF, TXT, PDF +In order of decreasing preference: LIT, MOBI, EPUB, HTML, PRC, RTF, TXT, PDF Why does the PDF conversion lose some images/tables? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -79,15 +111,12 @@ Library Management What formats does |app| read metadata from? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -|app| reads metadata from the following formats: LRF, PDF, LIT, RTF, OPF, MOBI, PRC, EPUB. In addition it can write metadata to: LRF, RTF, OPF +|app| reads metadata from the following formats: LRF, PDF, LIT, RTF, OPF, MOBI, PRC, EPUB, FB2, IMP, RB, HTML. In addition it can write metadata to: LRF, RTF, OPF Where are the book files stored? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -|app| use a database to store all books. When you import new books or convert an existing book, the book files are stored in compressed form in the database. The database is a single file named `library1.db` and you can see where it is (or change its location) by clicking the configuration button (the button with the icon of a hammer next to the search bar). +When you first run |app|, it will ask you for a folder in which to store your books. Whenever you add a book to |app|, it will copy the book into that folder. Books in the folder are nicely arranged into sub-folders by Author and Title. Metadata about the books is stored in the file ``metadata.db`` (which is a sqlite database). -Can I save my books to the disk? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can save your books to the disk by selecting the books and clicking the "Save to disk" button. Your books will be saved in nicely organized folders. Content From The Web --------------------- @@ -134,15 +163,16 @@ The graphical user interface of |app| is not starting on Windows? There can be several causes for this: * **Any windows version**: Try running it as Administrator (Right click on the icon ans select "Run as Administrator") - * **Any windows version**: Search for the files `calibre2.ini` and `calibre.ini` on your computer and delete them. Search for the file `library1.db` and rename it (this file contains all your converted books so deleting it is not a good idea. Now try again. - * **Windows Vista**: If the folder :file:`C:\Users\Your User Name\AppData\Local\VirtualStore\Program Files\calibre` exists, delete it. Uninstall |app|. Reboot. Re-install. + * **Any windows version**: If this happens during an initial run of calibre, try deleting the folder you chose for your ebooks and restarting calibre. + * **Windows Vista**: If the folder :file:`C:\\Users\\Your User Name\\AppData\\Local\\VirtualStore\\Program Files\\calibre` exists, delete it. Uninstall |app|. Reboot. Re-install. * **Any windows version**: Search your computer for a folder named :file:`_ipython`. Delete it and try again. + * **Any windows version**: Try disabling any antivirus program you have running and see if that fixes it. Also try diabling any firewall software that prevents connections to the local computer. If it still wont launch, start a command prompt (press the windows key and R; then type :command:`cmd.exe` in the Run dialog that appears). At the command prompt type the following command and press Enter:: calibre-debug -c "from calibre.gui2.main import main; main()" -Post any output you see in a help message on the `Forums `_. +Post any output you see in a help message on the `Forum `_. I want some feature added to |app|. What can I do? diff --git a/src/calibre/manual/glossary.rst b/src/calibre/manual/glossary.rst index 4a366ae491..8ae69f5ff9 100644 --- a/src/calibre/manual/glossary.rst +++ b/src/calibre/manual/glossary.rst @@ -27,4 +27,4 @@ Glossary **URL** *(Uniform Resource Locator)* for example: ``http://example.com`` regexp - **Regular expressions** provide a concise and flexible means for identifying strings of text of interest, such as particular characters, words, or patterns of characters. See http://docs.python.org/lib/re-syntax.html for the syntax of regular expressions used in python. + **Regular expressions** provide a concise and flexible means for identifying strings of text of interest, such as particular characters, words, or patterns of characters. See `regexp syntax `_ for the syntax of regular expressions used in python. diff --git a/src/calibre/manual/gui.rst b/src/calibre/manual/gui.rst index 9e5afd2bd0..f53584fb1b 100644 --- a/src/calibre/manual/gui.rst +++ b/src/calibre/manual/gui.rst @@ -225,6 +225,10 @@ will be interpreted to have the title: Foundation and Earth and author: Isaac As .. tip:: If the filename does not contain the hyphen, the regular expression will fail. +.. tip:: + If you want to only use metadata guessed from filenames and not metadata read from the file itself, you can tell |app| to do this, via the configuration dialog, accessed by the button to the right + of the search box. + .. _book_details: Book Details diff --git a/src/calibre/manual/index.rst b/src/calibre/manual/index.rst index 1a11820d9c..cfda23762a 100644 --- a/src/calibre/manual/index.rst +++ b/src/calibre/manual/index.rst @@ -29,6 +29,7 @@ Sections conversion metadata faq + xpath glossary Convenience diff --git a/src/calibre/manual/xpath.rst b/src/calibre/manual/xpath.rst new file mode 100644 index 0000000000..9db3783dec --- /dev/null +++ b/src/calibre/manual/xpath.rst @@ -0,0 +1,108 @@ +.. include:: global.rst + +.. _xpath-tutorial: + +XPath Tutorial +============== + +In this tutorial, you will be given a gentle introduction to +`XPath `_, a query language that can be +used to select arbitrary parts of `HTML `_ +documents in |app|. XPath is a widely +used standard, and googling it will yield a ton of information. This tutorial, +however, focuses on using XPath for ebook related tasks like finding chapter +headings in an unstructured HTML document. + +.. contents:: Contents + :depth: 1 + :local: + +Selecting by tagname +---------------------------------------- + +The simplest form of selection is to select tags by name. For example, +suppose you want to select all the ``

    `` tags in a document. The XPath +query for this is simply:: + + //h2 (Selects all

    tags) + +The prefix `//` means *search at any level of the document*. Now suppose you +want to search for ```` tags that are inside ```` tags. That can be +achieved with:: + + //a/span (Selects tags inside tags) + +If you want to search for tags at a particular level in the document, change +the prefix:: + + /body/div/p (Selects

    tags that are children of

    tags that are + children of the tag) + +This will match only ``

    A very short ebook to demonstrate the use of XPath.

    `` +in the `Sample ebook`_ but not any of the other ``

    `` tags. + +Now suppose you want to select both ``

    `` and ``

    `` tags. To do that, +we need a XPath construct called *predicate*. A :dfn:`predicate` is simply +a test that is used to select tags. Tests can be arbitrarily powerful and as +this tutorial progresses, you will see more powerful examples. A predicate +is created by enclosing the test expression in square brackets:: + +//*[name()='h1' or name()='h2'] + +There are several new features in this XPath expression. The first is the use +of the wildcard ``*``. It means *match any tag*. Now look at the test expression +``name()='h1' or name()='h2'``. :term:`name()` is an example of a *built-in function*. +It simply evaluates to the name of the tag. So by using it, we can select tags +whose names are either `h1` or `h2`. XPath has several useful built-in functions. +A few more will be introduced in this tutorial. + +Selecting by attributes +----------------------- + +To select tags based on their attributes, the use of predicates is required:: + + //*[@style] (Select all tags that have a style attribute) + //*[@class="chapter"] (Select all tags that have class="chapter") + //h1[@class="bookTitle"] (Select all h1 tags that have class="bookTitle") + +Here, the ``@`` operator refers to the attributes of the tag. You can use some +of the `XPath built-in functions`_ to perform more sophisticated +matching on attribute values. + + +Selecting by tag content +------------------------ + +Using XPath, you can even select tags based on the text they contain. The best way to do this is +to use the power of *regular expressions* via the built-in function :term:`re:test()`:: + + //h2[re:test(., 'chapter|section', 'i')] (Selects

    tags that contain the words chapter or + section) + +Here the ``.`` operator refers to the contents of the tag, just as the ``@`` operator referred +to its attributes. + + +Sample ebook +------------ + +.. literalinclude:: xpath.xhtml + :language: html + +XPath built-in functions +------------------------ + +.. glossary:: + + name() + The name of the current tag. + + contains() + ``contains(s1, s2)`` returns `true` if s1 contains s2. + + re:test() + ``re:test(src, pattern, flags)`` returns `true` if the string `src` matches the + regular expression `pattern`. A particularly useful flag is ``i``, it makes matching + case insensitive. A good primer on the syntax for regular expressions can be found + at `regexp syntax `_ + diff --git a/src/calibre/manual/xpath.xhtml b/src/calibre/manual/xpath.xhtml new file mode 100644 index 0000000000..7468e3d856 --- /dev/null +++ b/src/calibre/manual/xpath.xhtml @@ -0,0 +1,19 @@ + + + A very short ebook + + + +

    A very short ebook

    +

    Written by Kovid Goyal

    +
    +

    A very short ebook to demonstrate the use of XPath.

    +
    + +

    Chapter One

    +

    This is a truly fascinating chapter.

    + +

    Chapter Two

    +

    A worthy continuation of a fine tradition.

    + + diff --git a/src/calibre/parallel.py b/src/calibre/parallel.py index 0a028a16bd..6b19d7ba49 100644 --- a/src/calibre/parallel.py +++ b/src/calibre/parallel.py @@ -24,10 +24,11 @@ In the second mode, the controller can also send the worker STOP messages, in wh the worker interrupts the job and dies. The sending of progress and console output messages is buffered and asynchronous to prevent the job from being IO bound. ''' -import sys, os, gc, cPickle, traceback, atexit, cStringIO, time, signal, \ - subprocess, socket, collections, binascii, re, thread, tempfile +import sys, os, gc, cPickle, traceback, cStringIO, time, signal, \ + subprocess, socket, collections, binascii, re, thread, tempfile, atexit from select import select from threading import RLock, Thread, Event +from math import ceil from calibre.ptempfile import PersistentTemporaryFile from calibre import iswindows, detect_ncpus, isosx @@ -36,20 +37,33 @@ DEBUG = False #: A mapping from job names to functions that perform the jobs PARALLEL_FUNCS = { - 'any2lrf' : + 'any2lrf' : ('calibre.ebooks.lrf.any.convert_from', 'main', dict(gui_mode=True), None), - 'lrfviewer' : + 'lrfviewer' : ('calibre.gui2.lrf_renderer.main', 'main', {}, None), - 'feeds2lrf' : + 'feeds2lrf' : ('calibre.ebooks.lrf.feeds.convert_from', 'main', {}, 'notification'), - 'render_table' : + 'render_table' : ('calibre.ebooks.lrf.html.table_as_image', 'do_render', {}, None), + + 'render_pages' : + ('calibre.ebooks.lrf.comic.convert_from', 'render_pages', {}, 'notification'), - 'comic2lrf' : + 'comic2lrf' : ('calibre.ebooks.lrf.comic.convert_from', 'do_convert', {}, 'notification'), + + 'any2epub' : + ('calibre.ebooks.epub.from_any', 'any2epub', {}, None), + + 'feeds2epub' : + ('calibre.ebooks.epub.from_feeds', 'main', {}, 'notification'), + + 'comic2epub' : + ('calibre.ebooks.epub.from_comic', 'convert', {}, 'notification'), + } @@ -462,15 +476,17 @@ class Overseer(object): self.job.update_status(percent, msg) elif word == 'ERROR': self.write('OK') - self.job.excetion, self.job.traceback = cPickle.loads(msg) + exception, traceback = cPickle.loads(msg) + self.job.output(u'%s\n%s'%(exception, traceback)) + self.job.exception, self.job.traceback = exception, traceback return True else: self.terminate() self.job.exception = ControlError('Worker sent invalid msg: %s'%repr(msg)) return - if not self.worker_status.is_alive() or time.time() - self.last_report > 180: + if not self.worker_status.is_alive() or time.time() - self.last_report > 380: self.terminate() - self.job.exception = ControlError('Worker process died unexpectedly with returncode: %s'%str(self.process.returncode)) + self.job.exception = ControlError('Worker process died unexpectedly') return class JobKilled(Exception): @@ -529,7 +545,10 @@ class Job(object): self.percent = percent self.msg = msg if self.job_manager is not None: - self.job_manager.status_update(self) + try: + self.job_manager.status_update(self) + except: + traceback.print_exc() def status(self): if self.is_running: @@ -644,6 +663,25 @@ class Server(Thread): self.result_lock = RLock() self.pool_lock = RLock() self.start() + + def split(self, tasks): + ''' + Split a list into a list of sub lists, with the number of sub lists being + no more than the number of workers this server supports. Each sublist contains + two tuples of the form (i, x) where x is an element fro the original list + and i is the index of the element x in the original list. + ''' + ans, count, pos = [], 0, 0 + delta = int(ceil(len(tasks)/float(self.number_of_workers))) + while count < len(tasks): + section = [] + for t in tasks[pos:pos+delta]: + section.append((count, t)) + count += 1 + ans.append(section) + pos += delta + return ans + def close(self): try: @@ -657,6 +695,21 @@ class Server(Thread): if job.job_manager is not None: job.job_manager.add_job(job) + def poll(self): + ''' + Return True if the server has either working or queued jobs + ''' + with self.job_lock: + with self.working_lock: + return len(self.jobs) + len(self.working) > 0 + + def wait(self, sleep=1): + ''' + Wait until job queue is empty + ''' + while self.poll(): + time.sleep(sleep) + def run(self): while True: job = None @@ -814,8 +867,14 @@ def get_func(name): func = getattr(module, func) return func, kwdargs, notification +_atexit = collections.deque() +def myatexit(func, *args, **kwargs): + _atexit.append((func, args, kwargs)) + def work(client_socket, func, args, kwdargs): sys.stdout.last_report = time.time() + orig = atexit.register + atexit.register = myatexit try: func, kargs, notification = get_func(func) if notification is not None and hasattr(sys.stdout, 'notify'): @@ -826,7 +885,18 @@ def work(client_socket, func, args, kwdargs): sys.stdout.send() return res finally: + atexit.register = orig sys.stdout.last_report = None + while True: + try: + func, args, kwargs = _atexit.pop() + except IndexError: + break + try: + func(*args, **kwargs) + except (Exception, SystemExit): + continue + time.sleep(5) # Give any in progress BufferedSend time to complete @@ -856,10 +926,11 @@ def worker(host, port): write(client_socket, 'RESULT:'+ cPickle.dumps(result)) except BaseException, err: exception = (err.__class__.__name__, unicode(str(err), 'utf-8', 'replace')) - tb = traceback.format_exc() + tb = unicode(traceback.format_exc(), 'utf-8', 'replace') msg = 'ERROR:'+cPickle.dumps((exception, tb),-1) write(client_socket, msg) - if read(client_socket, 10) != 'OK': + res = read(client_socket, 10) + if res != 'OK': break gc.collect() elif msg == 'PING:': diff --git a/src/calibre/ptempfile.py b/src/calibre/ptempfile.py index 74831f95aa..8a1cac4a54 100644 --- a/src/calibre/ptempfile.py +++ b/src/calibre/ptempfile.py @@ -1,3 +1,4 @@ +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ @@ -8,30 +9,6 @@ import tempfile, os, atexit, shutil from calibre import __version__, __appname__ -class _TemporaryFileWrapper(object): - """ - Temporary file wrapper - - This class provides a wrapper around files opened for - temporary use. In particular, it seeks to automatically - remove the file when the object is deleted. - """ - - def __init__(self, _file, name): - self.file = _file - self.name = name - atexit.register(cleanup, name) - - def __getattr__(self, name): - _file = self.__dict__['file'] - a = getattr(_file, name) - if type(a) != type(0): - setattr(self, name, a) - return a - - def __del__(self): - self.close() - def cleanup(path): try: import os @@ -40,18 +17,36 @@ def cleanup(path): except: pass -def PersistentTemporaryFile(suffix="", prefix="", dir=None): +class PersistentTemporaryFile(object): """ - Return a temporary file that is available even after being closed on + A file-like object that is a temporary file that is available even after being closed on all platforms. It is automatically deleted on normal program termination. - Uses tempfile.mkstemp to create the file. The file is opened in mode 'wb'. """ - if prefix == None: - prefix = "" - fd, name = tempfile.mkstemp(suffix, __appname__+"_"+ __version__+"_" + prefix, - dir=dir) - _file = os.fdopen(fd, 'w+b') - return _TemporaryFileWrapper(_file, name) + _file = None + + def __init__(self, suffix="", prefix="", dir=None, mode='w+b'): + if prefix == None: + prefix = "" + fd, name = tempfile.mkstemp(suffix, __appname__+"_"+ __version__+"_" + prefix, + dir=dir) + self._file = os.fdopen(fd, 'w+b') + self._name = name + atexit.register(cleanup, name) + + def __getattr__(self, name): + if name == 'name': + return self.__dict__['_name'] + return getattr(self.__dict__['_file'], name) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __del__(self): + self.close() + def PersistentTemporaryDirectory(suffix='', prefix='', dir=None): ''' @@ -61,4 +56,22 @@ def PersistentTemporaryDirectory(suffix='', prefix='', dir=None): tdir = tempfile.mkdtemp(suffix, __appname__+"_"+ __version__+"_" +prefix, dir) atexit.register(shutil.rmtree, tdir, True) return tdir - + +class TemporaryDirectory(object): + ''' + A temporary directory to be used in a with statement. + ''' + def __init__(self, suffix='', prefix='', dir=None, keep=False): + self.suffix = suffix + self.prefix = prefix + self.dir = dir + self.keep = keep + + def __enter__(self): + self.tdir = tempfile.mkdtemp(self.suffix, __appname__+"_"+ __version__+"_" +self.prefix, self.dir) + return self.tdir + + def __exit__(self, *args): + if not self.keep and os.path.exists(self.tdir): + shutil.rmtree(self.tdir, ignore_errors=True) + diff --git a/src/calibre/startup.py b/src/calibre/startup.py index 347a1fab93..fc2749323a 100644 --- a/src/calibre/startup.py +++ b/src/calibre/startup.py @@ -12,17 +12,22 @@ from gettext import GNUTranslations # Default translation is NOOP import __builtin__ __builtin__.__dict__['_'] = lambda s: s - -from calibre.constants import iswindows, isosx, islinux, isfrozen + +from calibre.constants import iswindows, preferred_encoding, plugins +from calibre.utils.config import prefs from calibre.translations.msgfmt import make _run_once = False if not _run_once: _run_once = True + ################################################################################ # Setup translations - + def get_lang(): + lang = prefs['language'] + if lang is not None: + return lang lang = locale.getdefaultlocale()[0] if lang is None and os.environ.has_key('LANG'): # Needed for OS X try: @@ -34,7 +39,7 @@ if not _run_once: if match: lang = match.group() return lang - + def set_translator(): # To test different translations invoke as # LC_ALL=de_DE.utf8 program @@ -42,7 +47,7 @@ if not _run_once: from calibre.translations.compiled import translations except: return - lang = get_lang() + lang = get_lang() if lang: buf = None if os.access(lang+'.po', os.R_OK): @@ -54,9 +59,9 @@ if not _run_once: if buf is not None: t = GNUTranslations(buf) t.install(unicode=True) - + set_translator() - + ################################################################################ # Initialize locale try: @@ -68,37 +73,10 @@ if not _run_once: locale.setlocale(dl[0]) except: pass - - ################################################################################ - # Load plugins - if isfrozen: - if iswindows: - plugin_path = os.path.join(os.path.dirname(sys.executable), 'plugins') - sys.path.insert(1, os.path.dirname(sys.executable)) - elif isosx: - plugin_path = os.path.join(getattr(sys, 'frameworks_dir'), 'plugins') - elif islinux: - plugin_path = os.path.join(getattr(sys, 'frozen_path'), 'plugins') - sys.path.insert(0, plugin_path) - else: - import pkg_resources - plugins = getattr(pkg_resources, 'resource_filename')('calibre', 'plugins') - sys.path.insert(0, plugins) - - plugins = {} - for plugin in ['pictureflow', 'lzx', 'msdes'] + \ - (['winutil'] if iswindows else []) + \ - (['usbobserver'] if isosx else []): - try: - p, err = __import__(plugin), '' - except Exception, err: - p = None - err = str(err) - plugins[plugin] = (p, err) - + ################################################################################ # Improve builtin path functions to handle unicode sensibly - + _abspath = os.path.abspath def my_abspath(path, encoding=sys.getfilesystemencoding()): ''' @@ -114,7 +92,7 @@ if not _run_once: if to_unicode: res = res.decode(encoding) return res - + os.path.abspath = my_abspath _join = os.path.join def my_join(a, *p): @@ -126,15 +104,15 @@ if not _run_once: _unicode = True break p = [i.encode(encoding) if isinstance(i, unicode) else i for i in p] - + res = _join(*p) if _unicode: res = res.decode(encoding) return res - + os.path.join = my_join - - + + ################################################################################ # Platform specific modules winutil = winutilerror = None @@ -144,6 +122,9 @@ if not _run_once: raise RuntimeError('Failed to load the winutil plugin: %s'%winutilerror) if len(sys.argv) > 1: sys.argv[1:] = winutil.argv()[1-len(sys.argv):] - + ################################################################################ - \ No newline at end of file + # Convert command line arguments to unicode + for i in range(1, len(sys.argv)): + if not isinstance(sys.argv[i], unicode): + sys.argv[i] = sys.argv[i].decode(preferred_encoding, 'replace') diff --git a/src/calibre/trac/bzr_commit_plugin.py b/src/calibre/trac/bzr_commit_plugin.py index 61d4fa1dd9..8cd8b53d09 100644 --- a/src/calibre/trac/bzr_commit_plugin.py +++ b/src/calibre/trac/bzr_commit_plugin.py @@ -45,7 +45,7 @@ class cmd_commit(_cmd_commit): password = config.get_user_option(prefix+'password') close_bug = config.get_user_option(prefix+'pattern') if close_bug is None: - close_bug = r'(Fix|Implement)\s+#(\d+)' + close_bug = r'(Fix|Implement|Fixes|Fixed|Implemented)\s+#(\d+)' close_bug_pat = re.compile(close_bug, re.IGNORECASE) match = close_bug_pat.search(msg) if not match: @@ -82,7 +82,7 @@ class cmd_commit(_cmd_commit): def run(self, message=None, file=None, verbose=False, selected_list=None, unchanged=False, strict=False, local=False, fixes=None, - author=None, show_diff=False): + author=None, show_diff=False, exclude=None): nick = config = bug = action = None if message: try: @@ -97,7 +97,7 @@ class cmd_commit(_cmd_commit): ret = _cmd_commit.run(self, message=message, file=file, verbose=verbose, selected_list=selected_list, unchanged=unchanged, strict=strict, local=local, fixes=fixes, - author=author, show_diff=show_diff) + author=author, show_diff=show_diff, exclude=exclude) if message and bug and action and nick and config: self.close_bug(bug, action, url, config) return ret diff --git a/src/calibre/trac/plugins/Changelog.py b/src/calibre/trac/plugins/Changelog.py index ff15329859..05f1b4456f 100644 --- a/src/calibre/trac/plugins/Changelog.py +++ b/src/calibre/trac/plugins/Changelog.py @@ -17,6 +17,7 @@ BZR_PATH = '/var/bzr/code/calibre/trunk' class ChangelogFormatter(blog.LogFormatter): supports_tags = True + supports_merge_revisions = True def __init__(self, num_of_versions=20): self.num_of_versions = num_of_versions @@ -38,7 +39,7 @@ class ChangelogFormatter(blog.LogFormatter): self.messages = collections.deque() else: - if re.search(r'[a-zA-Z]', msg): + if re.search(r'[a-zA-Z]', msg) and len(msg.strip()) > 5: if 'translation' not in msg and not msg.startswith('IGN'): self.messages.append(msg.strip()) @@ -63,10 +64,10 @@ class ChangeLogMacro(WikiMacroBase): txt = bzr_log_to_txt().encode('ascii', 'xmlcharrefreplace') out = StringIO() Formatter(formatter.env, formatter.context).format(txt, out) - return Markup(out.getvalue()) + return Markup(out.getvalue().decode('utf8')) if __name__ == '__main__': - print bzr_log_to_txt() + print bzr_log_to_txt() diff --git a/src/calibre/trac/plugins/download.py b/src/calibre/trac/plugins/download.py index 15ee30b09a..ca5ecabed4 100644 --- a/src/calibre/trac/plugins/download.py +++ b/src/calibre/trac/plugins/download.py @@ -31,11 +31,12 @@ class Distribution(object): ('libusb', '0.1.12', None, None, None), ('Qt', '4.4.0', 'qt', 'libqt4-core libqt4-gui', 'qt4'), ('PyQt', '4.4.2', 'PyQt4', 'python-qt4', 'PyQt4'), - ('mechanize for python', '0.1.7b', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'), + ('mechanize for python', '0.1.8', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'), ('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'), ('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'), ('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'), - ('lxml', '1.3.3', 'lxml', 'python-lxml', 'python-lxml'), + ('lxml', '2.0.5', 'lxml', 'python-lxml', 'python-lxml'), + ('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-beautifulsoup'), ('help2man', '1.36.4', 'help2man', 'help2man', 'help2man'), ] @@ -44,8 +45,8 @@ class Distribution(object): INSTALLERS = ('emerge -avn', 'apt-get install', 'yum install') AS_ROOT = (True, False, True) - TITLEMAP = {'gentoo':'Gentoo', 'ubuntu':'Ubuntu Gutsy Gibbon', - 'fedora':'Fedora 8', 'debian':'Debian Sid', 'generic': 'Generic Unix'} + TITLEMAP = {'gentoo':'Gentoo', 'ubuntu':'Ubuntu Intrepid Ibex', + 'fedora':'Fedora 10', 'debian':'Debian sid', 'generic': 'Install from source'} MANUAL_MAP = { 'fedora' : '''
  • You have to upgrade Qt to at least 4.4.0 and PyQt to at least 4.4.2
  • ''', @@ -70,7 +71,7 @@ class Distribution(object): for dep in self.DEPENDENCIES: if len(cmd) > 70+offset: offset += 70 - cmd += pre + cmd += pre cmd += ' ' if dep[index]: cmd += dep[index] self.command = cmd.strip() @@ -125,13 +126,14 @@ class Download(Component): elif os == 'linux': return self.linux(req) elif 'binary' in os: - return self.linux_binary(req) + return self.linux_binary(req) else: return self.linux_distro(req, os) def linux_distro(self, req, os): + version = self.version_from_filename() distro = Distribution(os) - data = dict(distro=distro,title=distro.title) + data = dict(distro=distro,title=distro.title, version=version) return 'distro.html', data, None def top_level(self, req): @@ -142,7 +144,7 @@ class Download(Component): ] data = dict(title='Get ' + __appname__, operating_systems=operating_systems, width=200, - font_size='xx-large') + font_size='xx-large', top_level=True) return 'download.html', data, None def version_from_filename(self): @@ -178,7 +180,9 @@ for one device. In order to resolve the conflict: You can uninstall a driver by right clicking on it and selecting uninstall. -
  • Once the drivers have been uninstalled, uninstall %(appname)s. Reboot. Reinstall %(appname)s.
  • +
  • Once the drivers have been uninstalled, find the file prs500.inf (it will be in the +driver folder in the folder in which you installed %(appname)s. Right click on it and +select Install.
  • @@ -225,14 +229,14 @@ If not, head over to

    $title

    - See the
    Changelog for the changes in the latest version. Note: As of 0.4.80 this install - will not work on 64-bit CPUs. Try the precompiled binary available here instead. + See the Changelog for the changes in the latest version. Note: As of 0.4.80 this install + will not work on 64-bit CPUs. Try the precompiled binary available here instead.
    First verify that you have a sufficiently new installation of python
    python --version
    should return at least 2.5.1
    @@ -35,8 +35,13 @@
    1. Make sure that your system has python >= 2.5
    2. -
    3. Install the various dependencies listed below: Make sure that any python packages are installed into python2.5 (e.g. setuptools, python-imaging, PyQt4, etc)
    4. -
    5. As root run the command
      easy_install-2.5 -U TTFQuery calibre && calibre_postinstall
    6. +
    7. Install the various dependencies listed below: Make sure that any python packages are installed into python2.5 (e.g. setuptools, python-imaging, PyQt4, etc). You will also have to install the development versions of the packages (these packages usually have -dev added to their names).
    8. +
    9. Run the following commands in a terminal: +
      +wget -O- http://calibre.kovidgoyal.net/downloads/calibre-${version}.tar.gz | tar xvz 
      +cd calibre*
      +python setup.py build && sudo python setup.py install
      +            

    Dependencies

    @@ -58,27 +63,6 @@ -

    Post Installation

    - Connect the SONY Reader to the USB port. As root, test your installation by -
    prs500 info
    -

    - This should return some miscellaneous information about your reader. If it works your reader is being recognized by calibre. - On some distributions, you have to give non-root users access to the reader devices. - First check what group the reader devices are assigned to by -

    ls -l /dev/sd?
    - If you've just plugged in your reader, the reader devices should be at the bottom of the list. On - my system I get -
    -brw-r----- 1 root disk 8,  0 2008-05-27 13:50 /dev/sda
    -brw-r----- 1 root disk 8, 16 2008-05-27 13:50 /dev/sdb
    -brw-r----- 1 root disk 8, 32 2008-05-28 07:43 /dev/sdc
    -brw-r----- 1 root disk 8, 48 2008-05-28 07:43 /dev/sdd
    -brw-r----- 1 root disk 8, 64 2008-05-28 07:43 /dev/sde
    -        
    - Thus the group needed is disk. Add yourself to the group with the command -
    gpasswd -a username groupname
    -

    - Now reboot and you're done! diff --git a/src/calibre/trac/plugins/templates/download.html b/src/calibre/trac/plugins/templates/download.html index b4d401c38b..639e656e5c 100644 --- a/src/calibre/trac/plugins/templates/download.html +++ b/src/calibre/trac/plugins/templates/download.html @@ -11,6 +11,11 @@ +

    If you have a 64bit computer, or an outdated operating system, the distribution + specific installation may not work for you. In that case, first try the binary installer. + If that also does not work, your only recourse is to try to install from source. In order + to do that you will have to install all the dependencies as well as the -dev package of PyQt4. +

    $title

    diff --git a/src/calibre/translations/__init__.py b/src/calibre/translations/__init__.py index 9aca9e9fca..95bb3cd65e 100644 --- a/src/calibre/translations/__init__.py +++ b/src/calibre/translations/__init__.py @@ -3,55 +3,38 @@ __copyright__ = '2008, Kovid Goyal ' ''' Manage translation of user visible strings. ''' -import sys, os, cStringIO, tempfile, subprocess, functools, tarfile, re, time, \ - glob, urllib2, shutil -check_call = functools.partial(subprocess.check_call, shell=True) +import shutil, tarfile, re, os, subprocess, urllib2 -try: - from calibre.translations.pygettext import main as pygettext - from calibre.translations.msgfmt import main as msgfmt -except ImportError: - cwd = os.getcwd() - sys.path.insert(0, os.path.dirname(os.path.dirname(cwd))) - from calibre.translations.pygettext import main as pygettext - from calibre.translations.msgfmt import main as msgfmt +language_codes = { + 'aa':'Afar','ab':'Abkhazian','af':'Afrikaans','am':'Amharic','ar':'Arabic','as':'Assamese','ay':'Aymara','az':'Azerbaijani', + 'ba':'Bashkir','be':'Byelorussian','bg':'Bulgarian','bh':'Bihari','bi':'Bislama','bn':'Bengali','bo':'Tibetan','br':'Breton', + 'ca':'Catalan','co':'Corsican','cs':'Czech','cy':'Welsh', + 'da':'Danish','de':'German','dz':'Bhutani', + 'el':'Greek','en':'English','eo':'Esperanto','es':'Spanish','et':'Estonian','eu':'Basque', + 'fa':'Persian','fi':'Finnish','fj':'Fiji','fo':'Faroese','fr':'French','fy':'Frisian', + 'ga':'Irish','gd':'Scots Gaelic','gl':'Galician','gn':'Guarani','gu':'Gujarati', + 'ha':'Hausa','he':'Hebrew','hi':'Hindi','hr':'Croatian','hu':'Hungarian','hy':'Armenian', + 'ia':'Interlingua','id':'Indonesian','ie':'Interlingue','ik':'Inupiak','is':'Icelandic','it':'Italian','iu':'Inuktitut', + 'ja':'Japanese','jw':'Javanese', + 'ka':'Georgian','kk':'Kazakh','kl':'Greenlandic','km':'Cambodian','kn':'Kannada','ko':'Korean','ks':'Kashmiri','ku':'Kurdish','ky':'Kirghiz', + 'la':'Latin','ln':'Lingala','lo':'Laothian','lt':'Lithuanian','lv':'Latvian, Lettish', + 'mg':'Malagasy','mi':'Maori','mk':'Macedonian','ml':'Malayalam','mn':'Mongolian','mo':'Moldavian','mr':'Marathi','ms':'Malay','mt':'Maltese','my':'Burmese', + 'na':'Nauru','nb':'Norwegian Bokmal','nds':'German,Low','ne':'Nepali','nl':'Dutch','no':'Norwegian', + 'oc':'Occitan','om':'(Afan) Oromo','or':'Oriya', + 'pa':'Punjabi','pl':'Polish','ps':'Pashto, Pushto','pt':'Portuguese', + 'qu':'Quechua', + 'rm':'Rhaeto-Romance','rn':'Kirundi','ro':'Romanian','ru':'Russian','rw':'Kinyarwanda', + 'sa':'Sanskrit','sd':'Sindhi','sg':'Sangho','sh':'Serbo-Croatian','si':'Sinhalese','sk':'Slovak','sl':'Slovenian','sm':'Samoan','sn':'Shona','so':'Somali','sq':'Albanian','sr':'Serbian','ss':'Siswati','st':'Sesotho','su':'Sundanese','sv':'Swedish','sw':'Swahili', + 'ta':'Tamil','te':'Telugu','tg':'Tajik','th':'Thai','ti':'Tigrinya','tk':'Turkmen','tl':'Tagalog','tn':'Setswana','to':'Tonga','tr':'Turkish','ts':'Tsonga','tt':'Tatar','tw':'Twi', + 'ug':'Uighur','uk':'Ukrainian','ur':'Urdu','uz':'Uzbek', + 'vi':'Vietnamese','vo':'Volapuk', + 'wo':'Wolof', + 'xh':'Xhosa', + 'yi':'Yiddish','yo':'Yoruba', + 'za':'Zhuang','zh':'Chinese','zu':'Zulu' +} -def source_files(): - ans = [] - for root, dirs, files in os.walk(os.path.dirname(os.getcwdu())): - for name in files: - if name.endswith('.py'): - ans.append(os.path.abspath(os.path.join(root, name))) - return ans - - -def create_pot(): - files = source_files() - buf = cStringIO.StringIO() - print 'Creating translations template' - tempdir = tempfile.mkdtemp() - pygettext(buf, ['-p', tempdir]+files) - src = buf.getvalue() - pot = os.path.join(tempdir, 'calibre.pot') - f = open(pot, 'wb') - f.write(src) - f.close() - print 'Translations template:', pot - return pot - - -def compile_translations(): - translations = {} - print 'Compiling translations...' - for po in glob.glob('*.po'): - lang = os.path.basename(po).partition('.')[0] - buf = cStringIO.StringIO() - print 'Compiling', lang - msgfmt(buf, [po]) - translations[lang] = buf.getvalue() - open('compiled.py', 'wb').write('translations = '+repr(translations)) - def import_from_launchpad(url): f = open('/tmp/launchpad_export.tar.gz', 'wb') shutil.copyfileobj(urllib2.urlopen(url), f) @@ -69,36 +52,25 @@ def import_from_launchpad(url): print 'Updating', '%6s'%po, '-->', out open(out, 'wb').write(tf.extractfile(next).read()) next = tf.next() - check_for_critical_bugs() + path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + print path + subprocess.check_call('python setup.py translations'.split(), cwd=path) return 0 - + def check_for_critical_bugs(): if os.path.exists('.errors'): shutil.rmtree('.errors') pofilter = ('pofilter', '-i', '.', '-o', '.errors', - '-t', 'accelerators', '-t', 'escapes', '-t', 'variables', + '-t', 'accelerators', '-t', 'escapes', '-t', 'variables', '-t', 'xmltags') subprocess.check_call(pofilter) errs = os.listdir('.errors') if errs: print 'WARNING: Translation errors detected' - print 'See the .errors directory and http://translate.sourceforge.net/wiki/toolkit/using_pofilter' + print 'See the .errors directory and http://translate.sourceforge.net/wiki/toolkit/using_pofilter' - -def main(args=sys.argv): - if len(args) > 1: - if args[1] == 'pot': - create_pot() - else: - import_from_launchpad(args[1]) - else: - compile_translations() - return 0 - if __name__ == '__main__': - cwd = os.getcwd() - sys.path.insert(0, os.path.dirname(os.path.dirname(cwd))) - - sys.exit(main()) + import sys + import_from_launchpad(sys.argv[1]) diff --git a/src/calibre/translations/bg.po b/src/calibre/translations/bg.po index ec2174f599..faac6994ee 100644 --- a/src/calibre/translations/bg.po +++ b/src/calibre/translations/bg.po @@ -6,253 +6,521 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.51\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-05-24 06:23+0000\n" "Last-Translator: Kovid Goyal \n" "Language-Team: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +msgid "" +"An XPath expression to detect chapter titles. The default is to consider " +"

    or\n" +"

    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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 element of the OPF file. \n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references resources like images, stylesheets, scripts, " +"etc. \n" +"If an OPF file is specified instead, the list of files in its " +"element\n" +"is used.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 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:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 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:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 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:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 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:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 msgid "" "Use the 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:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 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:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 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:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 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:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 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:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 tags are " "ignored." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. tags whose href matches will be ignored. Defaults " "to %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 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:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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

    tags, you would use \"h2,none,\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -263,12 +531,12 @@ msgid "" "has only a few elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -276,25 +544,25 @@ msgid "" "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 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:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -302,33 +570,33 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 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:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -336,7 +604,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -347,92 +615,114 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -441,7 +731,7 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -449,24 +739,24 @@ msgid "" "%prog converts mybook.fb2 to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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:24 +#: /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:22 +#: /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:24 +#: /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:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "" @@ -494,71 +784,71 @@ msgstr "" msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" 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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -569,7 +859,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -577,48 +867,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -636,7 +926,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "" @@ -653,7 +943,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:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "" @@ -692,20 +982,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -713,21 +1003,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -735,7 +1025,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -743,23 +1039,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -773,38 +1079,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -824,96 +1130,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /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:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -924,53 +1355,57 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "
    Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "
    Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.
    Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -978,99 +1413,116 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1078,10 +1530,335 @@ msgstr "" msgid "ERROR" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "

    There was an error reading from file:
    " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"

    They can be any words or phrases, separated by commas." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +msgid "" +"\n" +"\n" +"

    You can control how " +"calibre detects chapters using a XPath expression. To learn how to use XPath " +"expressions see the XPath " +"tutorial

    " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "" @@ -1165,34 +1942,6 @@ msgstr "" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "" @@ -1202,33 +1951,10 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "

    There was an error reading from file:
    " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1267,10 +1993,6 @@ msgid "" "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "No help available" msgstr "" @@ -1279,276 +2001,156 @@ msgstr "" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "" - -#: /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:264 -msgid "Change the title of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -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/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"

    They can be any words or phrases, separated by commas." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" 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:531 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" 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:533 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" 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:539 msgid "Enable auto &rotation of images" msgstr "" -#: /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:540 msgid "Insert &blank lines between paragraphs" 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:541 msgid "Ignore &tables" msgstr "" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" 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:544 msgid "Header" 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:545 msgid "&Show header" 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:546 msgid "&Header format:" 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:547 msgid "Override
    CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "" -#: /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:560 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" 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:565 msgid "&Page break before tag:" 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:566 msgid "&Force page break before tag:" 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:567 msgid "Force page break before &attribute:" 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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" 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:570 msgid "" "\n" "\n" +"\n" "

    " @@ -1559,36 +2161,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 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:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr "" @@ -1598,8 +2200,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1611,71 +2213,76 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 msgid "" "

    Enter your username and password for LibraryThing.com.
    If you " "do not have one, you can register " "for free!.

    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover.
    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "" @@ -1704,13 +2311,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "" @@ -2017,11 +2626,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2054,101 +2663,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to edit me

    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2168,15 +2778,15 @@ msgstr "" msgid "Changes will only take effect after a restart." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches for the search phrase %s were found." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "" @@ -2220,118 +2830,132 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "

    For help visit %s.kovidgoyal.net
    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "%s: %s by Kovid Goyal %%(version)s
    %%(device)s

    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" "

    The database of books on the reader is corrupted. Try the " @@ -2347,307 +2971,287 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "

    Books with the same title as the following already exist in the database. " "Add them anyway?

      " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "

      Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:

        %s
      " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "

      Could not save the following books to disk, because the %s format is not " "available for them:

        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -msgid "" -"

        Could not convert %d of %d books, because no suitable source format was " -"found.

          %s
        " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "

        An invalid database already exists at %s, delete it before trying to move " "the existing database.
        Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 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:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "Latest version: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the new features. " "Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author

        Words separated by spaces " "are ANDed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments

        Words separated by spaces are ANDed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2657,7 +3261,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2675,78 +3279,132 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "

        Browsing books by their covers is disabled.
        Import of pictureflow " "module failed:
        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"

        Could not convert %d of %d books, because no suitable source format was " +"found.

          %s
        " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2754,68 +3412,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2824,11 +3482,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2837,15 +3495,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2855,29 +3513,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2885,62 +3543,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "

        Copying books to %s

        " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "

        Migrating old database to ebook library in %s

        " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -2971,7 +3682,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -2992,210 +3817,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from tags. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/translations/ca.po b/src/calibre/translations/ca.po index b4c5ac770c..935017a2a9 100644 --- a/src/calibre/translations/ca.po +++ b/src/calibre/translations/ca.po @@ -10,14 +10,14 @@ msgid "" msgstr "" "Project-Id-Version: ca\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-05-24 06:21+0000\n" "Last-Translator: Kovid Goyal \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" #~ msgid "" @@ -63,6 +63,9 @@ msgstr "" #~ "lletres, famí­lia\" ( --serif-family \"%s, Times New Roman\")\n" #~ " " +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "&Ubicació de la base de dades (library1.db)" + #~ msgid "&Access Key;" #~ msgstr "Clau d'&accés;" @@ -143,47 +146,328 @@ msgstr "" #~ "font-weight:600;\">calibre: %1 de Kovid Goyal %2
        %3

        " -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Creat per " - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +msgid "" +"An XPath expression to detect chapter titles. The default is to consider " +"

        or\n" +"

        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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Desconegut" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 element of the OPF file. \n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references resources like images, stylesheets, scripts, " +"etc. \n" +"If an OPF file is specified instead, the list of files in its " +"element\n" +"is used.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Indique el títol. Per defecte: nom_del_fitxer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -191,49 +475,34 @@ msgstr "" "Indiqueu l'autor(s). Si indique més d'un autor, separeu el llistat amb " "comes. Per defecte: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Desconegut" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Indiqueu els comentaris." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Indiqueu la categoria." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Clau d'ordre per al tí­tol." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Clau d'ordre per a l'autor" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Editorial" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Camí­ al fitxer d'imatge per a utilitzar com a coberta" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -241,11 +510,11 @@ msgstr "" "Si es detecta un gràfic per a la coberta al fitxer d'entrada, utilitzar-la " "en lloc de la coberta especificada." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "Nom del fitxer de destí­. Per defecte, deriva del fitxer d'entrada" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -253,33 +522,33 @@ msgstr "" "Renderitza les taules HTML com a blocs de text en lloc de les taules " "actuals. És necessari si el fitxer HTML conté taules massa grans o complexes." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Activa la rotació automàtica de les imatges més grans que l'amplada de la " "pantalla." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "Fixa l'espai entre paraules en punts. Per defecte: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Separa els paràgrafs amb lí­nies buides." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "" "Afegeix la capçalera a totes les pàgines, ficant el tí­tol i l'autor." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -287,7 +556,7 @@ msgstr "" "Estableix el format de la capçalera: %a es reemplaça per l'autor i %t pel " "tí­tol. Per defecte: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -295,7 +564,7 @@ msgstr "" "Substitueix la CSS. Pot indicar-se tant un camí­ a la fulla CSS alternativa, " "com una cadena. En aquest últim cas, la cadena s'interpreta com a CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 msgid "" "Use the 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 " @@ -305,13 +574,13 @@ msgstr "" "s'afegeixen els fitxers HTML al LRF. Cal que el fitxer .opf sigui a la " "mateixa carpeta que el fitxer HTML base." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 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:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -321,13 +590,13 @@ msgstr "" "lí­nia en FONT_DELTA punts. FONT_DELTA pot ser una fracció. Si és un valor " "negatiu, la grandària de la lletra disminueix." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 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:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -337,35 +606,35 @@ msgstr "" "determina la resolució i la grandària de la pantalla del dispositiu, entre " "d'altres. Per defecte:%s Perfils suportats: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Marge esquerre de la pàgina. Per defecte: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Marge dret de la pàgina. Per defecte: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Marge superior de la pàgina. Per defecte: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Marge inferior de la pàgina. Per defecte: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 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:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 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:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 tags are " @@ -375,21 +644,21 @@ msgstr "" "(cero) vol dir que no són seguits. Amb un valor negatiu, ignora les marques " "." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. tags whose href matches will be ignored. Defaults " "to %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -397,15 +666,17 @@ msgstr "" "Expressió regular utilitzada per a detectar els tí­tols dels capí­tols. " "Cerca a les marques de encapçalament (h1-h6). Per defecte: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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

        tags, you would use \"h2,none,\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -423,12 +694,12 @@ msgstr "" "llargues, que alentirien al canvi de fulla del fitxer LRF. Aquesta opció " "s'ignora si la pàgina actual en té pocs elements." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -440,16 +711,16 @@ msgstr "" "exemple, amb \"h\\d,class,chapter\", serien coincidents totes les marques de " "encapçalament amb l'atribut class=\"chapter\". Per defecte: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" "Pre-processa els fitxers Baen HTML per a millorar el fitxer LRF generat." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -457,11 +728,11 @@ msgstr "" "Cal que afegiu aquesta opció per a fitxers generats amb pdftohtml, si no " "voleu que la conversió falli." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Utilitzeu aquesta opció per a fitxers html0 de Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -469,27 +740,27 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "Famí­lia de lletres serif per a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "Famí­lia de lletres sans-serif per a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "Famí­lia de lletres monoespaiades per a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -497,7 +768,7 @@ msgstr "" "Minimitza l'ús de memòria, utilitzant més temps de processador. Empreu " "aquesta opció si el vostre equip no disposa de molta RAM." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -505,7 +776,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -516,92 +787,114 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -610,7 +903,7 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -618,24 +911,24 @@ msgid "" "%prog converts mybook.fb2 to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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:24 +#: /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:22 +#: /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:24 +#: /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:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "" @@ -663,71 +956,71 @@ msgstr "" msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" 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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -738,7 +1031,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -746,48 +1039,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -805,7 +1098,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Indiqueu el nom del llibre" @@ -822,7 +1115,7 @@ msgid "Set sort key for the author" msgstr "Indiqueu la clau d'ordenació per autor" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "Categoria a la que pertany el llibre. Per exemple, Història" @@ -861,20 +1154,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -882,21 +1175,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -904,7 +1197,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -912,23 +1211,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -942,38 +1251,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -993,96 +1302,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Directoris emprats amb freqüència" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Tí­tol" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Comentaris" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Camí" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formats" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TextLabel" +#: /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 "Trieu format" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Perfil:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -1093,53 +1527,57 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "
        Must be a directory." -msgstr "
        Cal que siga un directori." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Ubicació de la base de dades no vàlida " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Ubicació de la base de dades no vàlida" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "
        Must be a directory." +msgstr "
        Cal que siga un directori." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Ubicació de la base de dades no vàlida " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.
        Cannot write to " msgstr "Ubicació de la base de dades no vàlida.
        No es pot escriure " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Configuració" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "&Ubicació de la base de dades (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Cerca la nova ubicació de la base de dades" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1147,99 +1585,116 @@ msgstr "Cerca la nova ubicació de la base de dades" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Directoris emprats amb freqüència" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "Afegir el directori al llistat de directoris freqüents" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "Elimiar el directori al llistat de directoris freqüents" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1247,10 +1702,338 @@ msgstr "" msgid "ERROR" msgstr "ERROR" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Metadades" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Aparença" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Configuració de la pàgina" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Detecció de capí­tols" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "Milloreu la detecció de capí­tols i seccions." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "No pot llegir-se" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "No tens permissos per a llegir l'arxiu: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Error llegint l'arxiu" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "

        There was an error reading from file:
        " +msgstr "

        Error llegint de l'arxiu:
        " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " no és una imatge vàlida" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "No puc convertir-lo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Formats no disponibles" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "No puc convetir \"%s\" perquè el format no hi és suportat" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Coberta" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "Canvia la imatge de la &coberta:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Cerca una imatge per a utilitzar com a coberta d'aquest llibre." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Tí­tol: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Canvia el tí­tol del llibre" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Autor(s): " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Canvia l'autor(s). Per a especificar més d'un, separeu-los amb comes." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "Ord&re per autor:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Editorial: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Canvia l'editorial del llibre" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "Etique&tes: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"

        They can be any words or phrases, separated by commas." +msgstr "" +"Etiquetes per a categoritzar el llibre (especialment útil per a recerques). " +"

        Pot emprar-se qualsevol paraula o frase, separada per comes." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Sèries:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Llistat de sèries conegudes. Podeu afegir-hi de noves." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Índex de sèrie." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Llibre " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "Marge &Esquerre:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "Marge &Dret:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "Marge &Superior:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "Marge &Inferior:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +msgid "" +"\n" +"\n" +"

        You can control how " +"calibre detects chapters using a XPath expression. To learn how to use XPath " +"expressions see the XPath " +"tutorial

        " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Autor(s)" @@ -1336,34 +2119,6 @@ msgstr "Treballs actius" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Metadades" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Aparença" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Configuració de la pàgina" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Detecció de capí­tols" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Formats no disponibles" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "No puc convetir \"%s\" perquè el format no hi és suportat" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Trieu el format per convertir a LRF" @@ -1373,33 +2128,10 @@ msgid "Convert %s to LRF" msgstr "Converteix %s a LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Fixa els valors de conversió er defecte" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "No pot llegir-se" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "No tens permissos per a llegir l'arxiu: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Error llegint l'arxiu" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "

        There was an error reading from file:
        " -msgstr "

        Error llegint de l'arxiu:
        " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " no és una imatge vàlida" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1447,10 +2179,6 @@ msgstr "" "Configuració de la pàgina del dispositiu, especificant ,marges i grandària " "de la pantalla, entre d'altres." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "Milloreu la detecció de capí­tols i seccions." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "No help available" msgstr "Ajuda no disponible" @@ -1459,279 +2187,156 @@ msgstr "Ajuda no disponible" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Convertir a LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Categoria" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Opcions" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Coberta" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "Canvia la imatge de la &coberta:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Cerca una imatge per a utilitzar com a coberta d'aquest llibre." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "&Tí­tol: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Canvia el tí­tol del llibre" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Autor(s): " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Canvia l'autor(s). Per a especificar més d'un, separeu-los amb comes." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "Ord&re per autor:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Editorial: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Canvia l'editorial del llibre" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "Etique&tes: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"

        They can be any words or phrases, separated by commas." -msgstr "" -"Etiquetes per a categoritzar el llibre (especialment útil per a recerques). " -"

        Pot emprar-se qualsevol paraula o frase, separada per comes." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Sèries:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Llistat de sèries conegudes. Podeu afegir-hi de noves." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Índex de sèrie." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Llibre " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Grandària de lletra base:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " punts" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Lletres inserides" -#: /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:531 msgid "&Serif:" msgstr "&Serif:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif:" -#: /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:533 msgid "&Monospace:" msgstr "&Monoespaiada:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" msgstr "&Espaiat de les paraules:" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Activa la &rotació automàtica d'imatges" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "Inserta lí­nies &buides entre paràgrafs" -#: /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:541 msgid "Ignore &tables" msgstr "Ignora les &taules" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" msgstr "&Preprocessament:" -#: /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:544 msgid "Header" msgstr "Capçalera" -#: /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:545 msgid "&Show header" msgstr "&Mostrar capçalera" -#: /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:546 msgid "&Header format:" msgstr "&Format de la capçalera:" -#: /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:547 msgid "Override
        CSS" msgstr "Substitueix
        CSS" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "Marge &Esquerre:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " Pí­xels" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "Marge &Dret:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "Marge &Superior:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "Marge &Inferior:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Detecció basada en el tí­tol" -#: /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:560 msgid "&Disable chapter detection" msgstr "&Desactivar detecció de capí­tols" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "Expressió &Regular:" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" msgstr "Detecció basada en marques" -#: /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:565 msgid "&Page break before tag:" msgstr "Inserta un salt de &pàgina abans de la marca:" -#: /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:566 msgid "&Force page break before tag:" msgstr "&Força un salt de pàgina abans de la marca:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Força un salt de pàgina abans de l'&atribut:" -#: /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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" msgstr "Ajuda amb l'í­tem" -#: /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:570 msgid "" "\n" "\n" +"\n" "

        " @@ -1742,17 +2347,17 @@ msgid "Edit Meta information" msgstr "Editar Meta-informació" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Meta-informació" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "&Ordena autors: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1761,19 +2366,19 @@ msgstr "" "exemple,ordena Vicent A. Estellés com a Estellés, Vicent A." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Valoració:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Valora aquest llibre: 0-5 estreles" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " estreles" @@ -1783,8 +2388,8 @@ msgstr "Afe&geix les etiquetes: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1796,72 +2401,77 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 msgid "" "

        Enter your username and password for LibraryThing.com.
        If you " "do not have one, you can register " "for free!.

        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover.
        " msgstr "No puc aconseguir la coberta.
        " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "No puc aconseguir la coberta" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "No puc aconseguir la coberta" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Cal especificar un ISBN correcte per al llibre." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Edita la meta-informació" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Recull metadades des del servidor" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Formats disponibles" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Afegir un nou format per a aquest llibre a la base de dades" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" "Elimina els formats seleccionats per a aquest llibre de la base de dades." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Recolliu la coberta des del servidor" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "" @@ -1890,13 +2500,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Sèries" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Format" @@ -2203,11 +2815,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2240,101 +2852,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Treball" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Estat" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Progressió" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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 "En espera..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "Està treballant..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Cap" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Etiquetes" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formats" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book %s of %s." msgstr "Llibre %s de %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to edit me

        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Grandària (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Data" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Valoració" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Camí" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Marca de temps" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2354,15 +2967,15 @@ msgstr "Partició de mots" msgid "Changes will only take effect after a restart." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches for the search phrase %s were found." msgstr "No s'han trobat coincidències per al text \"%s\"." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "No s'han trobat coincidències" @@ -2406,118 +3019,132 @@ msgstr "Obre l'eBook" msgid "Configure" msgstr "Configura" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Error en la comunicació amb el dispositiu" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "

        For help visit %s.kovidgoyal.net
        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "%s: %s by Kovid Goyal %%(version)s
        %%(device)s

        " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "Envia a la memòria interna" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "Envia a la targeta de memòria" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Edita metadades individualment" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Edita metadades en massa" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Desa al disc" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Mostra" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Converteix individualment" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Converteix tots" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" "

        The database of books on the reader is corrupted. Try the " @@ -2533,189 +3160,156 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "

        Books with the same title as the following already exist in the database. " "Add them anyway?

          " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Sense espai al dispositiu" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "

          Cannot upload books to device there is no more free space available " msgstr "

          No puc desar llibres al dispositiu perquè no hi ha espai restant " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "No puc editar les meta-dades" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Cap llibre seleccionat" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:

            %s
          " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "No puc desar al disc" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "

          Could not save the following books to disk, because the %s format is not " "available for them:

            " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "No puc convertir-lo" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -msgid "" -"

            Could not convert %d of %d books, because no suitable source format was " -"found.

              %s
            " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Cap llibre seleccionat" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "No puc mostrar-lo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "No puc configurar-lo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "No puc configurar-lo amb treballs processant-se" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "

            An invalid database already exists at %s, delete it before trying to move " "the existing database.
            Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "No puc moure la base de dades" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Error comunicant amb el dispositiu" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2723,54 +3317,59 @@ msgstr "" "Hi ha hagut un error de comunicació amb el dispositiu. Lleve, torne a " "connectar el dispositiu i torne a iniciar el programa" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "Latest version: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the new features. " "Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "Re&cerca:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author

            Words separated by spaces " "are ANDed" @@ -2778,7 +3377,7 @@ msgstr "" "Recerca llibres pel tí­tol o l'autor.

            Els espais entre paraules es " "substitueixen per AND." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments

            Words separated by spaces are ANDed" @@ -2786,60 +3385,68 @@ msgstr "" "Recerca llibres pel tí­tol, l'autor, l'editorial, les etiquetes i els " "comentaris

            Els espais entre paraules es substitueixen per AND." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Reinicialitza la recerca ràpida" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Afegeix llibres" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Suprimeix llibres" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Esborra" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Edita la meta-informació" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "Envia al dispositiu" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Recull notí­cies (RSS)" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "Converteix Ebooks" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2849,7 +3456,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2867,41 +3474,91 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Treballs:" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "

            Browsing books by their covers is disabled.
            Import of pictureflow " "module failed:
            " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"

            Could not convert %d of %d books, because no suitable source format was " +"found.

              %s
            " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -2909,7 +3566,7 @@ msgstr "" "El Sony Reader\n" "%s està disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -2917,32 +3574,36 @@ msgstr "" "La targeta\n" "%s està disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2950,68 +3611,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3020,11 +3681,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3033,15 +3694,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3051,29 +3712,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3081,62 +3742,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "

            Copying books to %s

            " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "

            Migrating old database to ebook library in %s

            " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Creat per " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -3167,7 +3881,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3188,210 +4016,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from tags. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/translations/de.po b/src/calibre/translations/de.po index be9dde72ff..bda8ab4ad0 100644 --- a/src/calibre/translations/de.po +++ b/src/calibre/translations/de.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-08-04 11:27+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-29 13:13+0000\n" "Last-Translator: S. Dorscht \n" "Language-Team: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" @@ -55,9 +55,22 @@ msgstr "" #~ msgid "The author whoose book to search for." #~ msgstr "Der Autor des gesuchten Buches." +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "Speicherort der Bücherdatenbank (&library1.db)" + #~ msgid "&Access Key;" #~ msgstr "&Zugriffsschlüssel:" +#~ msgid "" +#~ "Cannot kill jobs that are communicating with the device as this may cause " +#~ "data corruption." +#~ msgstr "" +#~ "Kann Aufträge nicht abbrechen, die mit dem Gerät kommunizieren, da dies zu " +#~ "Datenverlust führen kann." + +#~ msgid "Cannot kill already completed jobs." +#~ msgstr "Kann schon fertiggestellte Aufträge nicht abbrechen." + #~ msgid "Cannot kill waiting jobs." #~ msgstr "Kann Aufträge in Warteliste nicht abbrechen." @@ -74,14 +87,78 @@ msgstr "" #~ "Speichern Sie den unten stehenden Text als Rezept.py Datei und senden Sie " #~ "die Datei an Freunde, damit sie dieses Rezept ebenfalls benutzen können." +#~ msgid "Copying database to " +#~ msgstr "Kopiere Datenbank nach " + +#~ msgid "" +#~ "Path to the calibre database. Default is to use the path stored in the " +#~ "settings." +#~ msgstr "" +#~ "Pfad zur Datenbank von calibre. Die Voreinstellung ist der in den " +#~ "Einstellungen gespeicherte Pfad." + +#~ msgid "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "List the books available in the calibre database. \n" +#~ msgstr "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "Listet die in der Datenbank von calibre verfügbaren Bücher auf. \n" + +#~ 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 "" +#~ "%prog add [options] Datei1 Datei2 Datei3 ...\n" +#~ "\n" +#~ "Fügt die angegebenen Dateien als Bücher zur Datenbank hinzu. Sie können auch " +#~ "Verzeichnisse angeben, sehen Sie sich dazu die zu den Verzeichnissen " +#~ "gehörigen Optionen weiter unten an. \n" + +#~ 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 "" +#~ "%%prog command [options] [arguments]\n" +#~ "\n" +#~ "%%prog ist die Befehlszeilenschnittstelle zur Bücher Datenbank von calibre. " +#~ "\n" +#~ "\n" +#~ "command ist eines der folgenden:\n" +#~ " %s\n" +#~ " \n" +#~ "Für Hilfe zu einem bestimmten Befehl (command): %%prog command --help\n" + +#~ 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\". Default is %default" +#~ msgstr "" +#~ "Erkenne einen Kapitelanfang anhand des Elements mit dem angegebenen " +#~ "Attribut. Das Format dieser Option ist tagname regexp,attribute " +#~ "name,attribute value regexp. Um zum Beispiel alle \"header\" (\"h\") " +#~ "Elemente mit dem Attribut class=\"chapter\" anzugleich, müsste man \"h\\" +#~ "d,class,chapter\" benutzen. Voreinstellung ist %default" + #~ msgid "" #~ "\n" #~ "\n" +#~ "\n" #~ "

            " @@ -91,53 +168,540 @@ msgstr "" #~ "\n" +#~ "\n" #~ "

            " -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sBenutzung%s: %s\n" +#~ 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 "" +#~ "\n" +#~ "%prog show_metadata [options] id\n" +#~ "\n" +#~ "Zeige die in der calibre Datenbank gespeicherten Meta-Daten für das durch " +#~ "die ID erkannte Buch. \n" +#~ "\"id\" ist eine ID Nummer des Befehls \"list\". \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Erstellt von " +#~ 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 "" +#~ "\n" +#~ "%prog set_metadata [options] id /verzeichnis/zu/metadata.opf\n" +#~ "\n" +#~ "Übernehme die Meta-Daten, die in der calibre Datenbank für das durch die ID " +#~ "erkannte Buch gespeichert werden,\n" +#~ "aus der OPF Datei metadata.opf. \"id\" ist eine ID Nummer des Befehls " +#~ "\"list\". Sie erhalten \n" +#~ "einen Eindruck über das OPF Format, wenn Sie die --as-opf Option mit dem \n" +#~ "Befehl show_metadata verwenden.\n" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ 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 "" +#~ "%prog export [options] ids \n" +#~ "\n" +#~ "Exportiert die durch IDs angegebenen Bücher (als durch Kommata getrennte " +#~ "Liste) in das Dateisystem.\n" +#~ "Der Export speichert alle Formate des Buches, sein Umschlagbild und die Meta-" +#~ "Daten (in \n" +#~ "einer OPF Datei). Sie erhalten ID Nummern mit dem Befehl \"list\". \n" + +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Konvertiert ein Comic einer CBZ oder CBR Datei in ein LRF eBook. \n" + +#~ msgid "Set defaults for conversion to LRF" +#~ msgstr "Voreinstellungen für die Konvertierung zu LRF Dateien setzen" + +#~ msgid "Convert comic %d of %d (%s)" +#~ msgstr "Konvertiere Comic %d von %d (%s)" + +#~ msgid "" +#~ "An XPath expression to detect chapter titles. The default is to consider " +#~ "

            or\n" +#~ "

            tags that contain the text \"chapter\" or \"book\" or \"section\" as " +#~ "chapter titles. \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 "" +#~ "Ein XPath Ausdruck zur Erkennung von Kapitelüberschriften. In der " +#~ "Voreinstellung werden

            oder

            Tags, \n" +#~ "die den Text \"chapter\" oder \"book\" oder \"section\" enthalten, als " +#~ "Kapitelüberschriften betrachtet. \n" +#~ "Der verwendete Ausdruck muss durch eine Liste von Elementen festgelegt sein. " +#~ "Zum Ausschalten der Kapitelerkennung \n" +#~ "verwenden Sie den Ausdruck \"/\". Weitere Hilfe zur Benutzung dieser " +#~ "Funktion finden Sie im XPath Tutorial des calibre \n" +#~ "User Manual.\n" + +#~ msgid "Don't add detected chapters to the Table of Contents" +#~ msgstr "Erkannte Kapitel nicht ins Inhaltsverzeichnis übernehmen" + +#~ msgid "Don't add links in the root HTML file to the Table of Contents" +#~ msgstr "" +#~ "Verknüpfungen aus der ursprünglichen HTML Datei nicht ins Inhaltsverzeichnis " +#~ "übernehmen" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Convert a HTML file to an EPUB ebook. Follows links in the HTML file. \n" +#~ msgstr "" +#~ "%prog [options] datei.html\n" +#~ "\n" +#~ "Konvertiert eine HTML Datei in ein EPUB eBook. Verfolgt Verknüpfungen in der " +#~ "HTML Datei. \n" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Follow all links in an HTML file and collect them into the specified " +#~ "directory.\n" +#~ "Also collects any references resources like images, stylesheets, scripts, " +#~ "etc. \n" +#~ msgstr "" +#~ "%prog [options] datei.html\n" +#~ "\n" +#~ "Verfolgt alle Verknüpfungen in einer HTML Datei und sammelt sie in dem " +#~ "angegebenen Verzeichnis.\n" +#~ "Sammelt zudem jegliche Hinweise und Quellen wie Bilder, Stylesheets, " +#~ "Skripte, etc. \n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "Konnte das Laufwerk %s nicht finden. Versuchen Sie einen Neustart." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "Im Reader ist keine Speicherkarte eingesteckt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Einstellungen zur Kontrolle der Konvertierung zu EPUB Dateien" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"EPUB Ausgabedatei. Falls nicht angegeben, wird es vom ursprünglichen " +"Dateinamen abgeleitet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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 "" +"Profil des Zielgeräts für das diese EPUB Datei gedacht ist. Die Einstellung " +"\"Kein\" erstellt eine geräteunabhängige EPUB Datei. Das Profil wird für " +"gerätespezifische Einschränkungen der EPUB Datei verwendet. Es gibt folgende " +"Wahlmöglichkeiten: " + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:63 +msgid "" +"Either the path to a CSS stylesheet or raw CSS. This CSS will override any " +"existing CSS declarations in the source files." +msgstr "" +"Entweder der Pfad zu einem CSS Stylesheet oder original CSS. Dieses CSS " +"überschreibt alle existierenden CSS Angaben in den Ursprungsdateien." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:64 +msgid "Control auto-detection of document structure." +msgstr "Kontrolle der automatischen Erkennung der Dokumentstruktur." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +msgid "" +"An XPath expression to detect chapter titles. The default is to consider " +"

            or\n" +"

            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 "" +"Ein XPath Ausdruck zur Erkennung von Kapitelüberschriften. In der " +"Voreinstellung werden

            oder\n" +"

            Tags verwendet, die die Worte \"chapter\",\"book\",\"section\" oder " +"\"part\" als Kapitelüberschriften\n" +"enthalten und genauso alle Tags, die class=\"chapter\" enthalten. \n" +"Der verwendete Ausdruck muss eine Liste von Elementen auswerten. Die " +"Kapitelerkennung wird durch die\n" +"Verwendung des Ausdrucks \"/\" ausgeschaltet. Ein Hilfe zur Verwendung " +"dieses Features gibt es im\n" +"XPath Tutorial im calibre User Manual.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:75 +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 "" +"Geben Sie an, wie erkannte Kapitel gekennzeichnet werden sollen. Der Wert " +"\"pagebreak\" fügt Seitenumbrüche vor Kapiteln ein. Der Wert \"rule\" fügt " +"eine Linie vor Kapiteln ein. Der Wert \"none\" schaltet die " +"Kapitelmarkierung aus und der Wert \"both\" verwendet sowohl Seitenumbrüche " +"als auch Linien zur Kapitelmarkierung." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:77 +msgid "Path to the cover to be used for this book" +msgstr "Pfad zum Umschlagbild, das für dieses Buch verwendet werden soll" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +msgid "" +"Use the cover detected from the source file in preference to the specified " +"cover." +msgstr "" +"Verwendet bevorzugt das aus der Ursprungsdatei gewonnene Umschlagbild " +"anstatt des angegebenen Umschlagbildes." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:83 +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 "" +"Kontrolle der automatischen Erstellung eines Inhaltsverzeichnisses. Falls " +"eine OPF Datei erkannt\n" +"wird und sie ein Inhaltsverzeichnis angibt, wird dieses verwendet anstatt zu " +"versuchen\n" +"ein Inhaltsverzeichnis automatisch zu erstellen.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:89 +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 "" +"Höchstzahl der Verknüpfungen, die in das Inhaltsverzeichnis eingefügt " +"werden. Zum Ausschalten auf 0 setzen. Voreinstellung ist: %default. " +"Verknüpfungen werden nur dann zum Inhaltsverzeichnis hinzugefügt, wenn " +"weniger Kapitel als in --toc-threshold angegeben erkannt werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "Automatisch erkannte Kapitel nicht zum Inhaltsverzeichnis hinzufügen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" +"Falls weniger Kapitel erkannt werden als in dieser Zahl angegeben, dann " +"werden Verknüpfungen zum Inhaltsverzeichnis hinzugefügt." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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 "" +"Normalerweise wird, falls die Ursprungsdatei schon ein Inhaltsverzeichnis " +"enthält, dieses anstelle des automatisch erkannten verwendet. Mit dieser " +"Option wird immer das automatisch erkannte Inhaltsverzeichnis verwendet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:97 +msgid "Control page layout" +msgstr "Einstellungen des Seitenlayouts" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" +"Oberen Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" +"Unteren Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" +"Linken Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" +"Rechten Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "Erstellte OPF Datei nach stdout ausgeben" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "Erstellte NCX Datei nach stdout ausgeben" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "Zwischendateien während des Verarbeitens mit html2epub beibehalten" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +msgid "" +"Extract the contents of the produced EPUB file to the specified directory." +msgstr "" +"Den Inhalt der erstellten EPUB Datei in das angegebene Verzeichnis " +"extrahieren." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Unbekannt" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "Konnte kein eBook im Archiv finden" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" +"%%prog [options] Dateiname\n" +"\n" +"Konvertiert eine große Anzahl von eBook Formaten in eine EPUB Datei. " +"Unterstützte Formate: %s\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 element of the OPF file. \n" +msgstr "" +"%prog [options] file.html|opf\n" +"\n" +"Konvertiert eine HTML Datei in ein EPUB eBook. Verfolgt Verknüpfungen in der " +"HTML Datei rekursiv.\n" +"Falls statt der HTML Datei eine OPF Datei angegeben wird, wird die Liste der " +"Verknüpfungen aus dem\n" +" Element der OPF Datei verwendet. \n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "Geben Sie eine Eingabedatei im HTML Format an." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +msgid "" +"Could not find reasonable point at which to split: %s Sub-tree size: %d KB" +msgstr "" +"Konnte keinen vernünftige Stelle zur Trennung finden: %s Unterbaumgröße: %d " +"KB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:85 +msgid "" +"\t\tToo much markup. Re-splitting without structure preservation. This may " +"cause incorrect rendering." +msgstr "" +"\t\tZu viel Textauszeichnung. Wieder-Aufteilung ohne Bewahrung der Struktur. " +"Dies kann zu falschem Rendering führen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:390 +msgid "Written processed HTML to " +msgstr "Verarbeitetes HTML wurde geschrieben in " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "Einstellungen zur Kontrolle der Durchforstung von HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "Ausgabeverzeichnis. Voreinstellung ist das aktuelle Verzeichnis." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" +"Zeichenkodierung für HTML Dateien. Die Voreinstellung ist automatisches " +"Erkennen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Erstellt die Ausgabe in eine ZIP Datei. Wird diese Option angegeben, sollte -" +"-output der Name einer Datei und nicht eines Verzeichnisses sein." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Kontrolliert die Verfolgung von Verknüpfungen in HTML Dateien." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" +"Durchforstet Verknüpfungen in HTML Dateien zuerst in die Breite. " +"Normalerweise werden sie zuerst in die Tiefe durchforstet" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Maximale Höhe der Rekursion bei der Verfolgung von Verknüpfungen in HTML " +"Dateien. Darf nicht negativ sein. 0 gibt an, dass keine Verknüpfungen in der " +"ursprünglichen HTML Datei verfolgt werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Geben Sie die Metadaten des erstellten eBooks an" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Geben Sie den Titel an. Voreinstellung ist automatische Ermittlung." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "Autor(en) des eBooks, als durch Kommata getrennte Liste." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "Metadaten aus der angegebenen OPF Datei laden" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Hilfreiche Einstellungen zur Fehlersuche" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" +"Noch ausführlicher bei der weiteren Verarbeitung vorgehen. Kann zur " +"Vergrößerung der Ausführlichkeit mehrfach angegeben werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" +"Ausgabe HTML ist \"hübsch gedruckt\" zur einfacheren Analyse durch " +"menschliche Wesen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references resources like images, stylesheets, scripts, " +"etc. \n" +"If an OPF file is specified instead, the list of files in its " +"element\n" +"is used.\n" +msgstr "" +"%prog [options] file.html|opf\n" +"\n" +"Folgt allen Verknüpfungen in einer HTML Datei und sammelt sie in das " +"angegebene Verzeichnis.\n" +"Sammelt zudem jegliche verwiesene Quellen wie Bilder, Stylesheets, Skripte, " +"usw.\n" +"Falls stattdessen eine OPF Datei angegeben wird, wird die Liste der Dateien " +"in ihrem Element\n" +"verwendet.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:813 msgid "%prog [options] LITFILE" msgstr "%prog [options] LITFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "Ausgabeverzeichnis. Voreinstellung ist akutelles Verzeichnis." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" +"Lesbares Format der extrahierten Textauszeichnung. Könnte sinnvolle " +"Freiräume abändern." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Hilfreich bei der Fehlersuche." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "OEB eBook erstellt in" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Geben Sie den Titel an. Voreinstellung: Dateiname." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -145,49 +709,34 @@ msgstr "" "Geben Sie den Autor an. Mehrere Autoren sollten durch Kommata getrennt " "angegeben werden. Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Unbekannt" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Geben Sie eine Bemerkung an." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Geben Sie eine Kategorie an." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Sortierung nach Titel" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Sortierung nach Autor" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Herausgeber" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Pfad zur Datei des Umschlagbildes" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -195,13 +744,13 @@ msgstr "" "Falls die Quelldatei ein Umschlagbild enthält, das Umschlagbild der " "Quelldatei benutzen, anstatt des angegebenen Umschlagbildes." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" "Ausgabedateiname. Die Voreinstellung leitet sich vom ursprünglichen " "Dateinamen ab." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -209,7 +758,7 @@ msgstr "" "HTML Tabellen als Textblöcke rendern und nicht als Tabellen. Dies ist " "notwendig, wenn die HTML Datei sehr große oder komplexe Tabellen enthält." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -220,27 +769,27 @@ msgstr "" "Option außer Gebrauch und wird bevorzugt behandelt. Um --font-delta zu " "benutzen, geben Sie 0 an. Voreinstellung: %defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Automatische Rotation von Bildern, die breiter als die Bildschirmbreite " "sind, einschalten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" "Wählen Sie den Abstand in Punkt zwischen einzelnen Wörtern. Die " "Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Paragraphen durch Leerzeilen trennen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Kopfzeile mit Titel und Autor für alle Seiten einfügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -248,7 +797,7 @@ msgstr "" "Wählen Sie das Format der Kopfzeile. %a wird durch den Autor und %t durch " "den Titel ersetzt. Die Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -256,7 +805,7 @@ msgstr "" "CSS überschreiben. Es kann ein Pfad zu einem CSS Stylesheet oder eine " "Zeichenfolge angegeben werden. Zeichenfolgen werden als CSS interpretiert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 msgid "" "Use the 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 " @@ -266,7 +815,7 @@ msgstr "" "in der die HTML Dateien zur LRF Datei hinzugefügt werden. Die OPF Datei muss " "sich im gleichen Verzeichnis wie die ursprüngliche HTML Datei befinden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -274,7 +823,7 @@ msgstr "" "Mindest-Zeileneinzug von Paragraphen (Zeileneinzug der ersten Zeile eines " "Paragraphen) in Punkt. Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -284,14 +833,14 @@ msgstr "" "vergrößern. FONT_DELTA kann ein Bruchteil sein. Falls FONT_DELTA negativ " "angegeben wird, wird die Schriftgröße verkleinert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." msgstr "" "Inhalt schwarz-weiß rendern anstatt in den in HTML oder CSS angegeben Farben." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -301,23 +850,23 @@ msgstr "" "unter anderem die Auflösung und die Bildschirmgröße des Zielgerätes fest. " "Voreinstellung: %s Unterstützte Profile: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Linker Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Rechter Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Oberer Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Unterer Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -325,7 +874,7 @@ msgstr "" "Tabellen in HTML als Bilder rendern (hilfreich, wenn das Dokument große oder " "komplexe Tabellen enthält)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -333,7 +882,7 @@ msgstr "" "Textgröße in gerenderten Tabellen um diesen Faktor erhöhen. Voreinstellung " "ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 tags are " @@ -343,7 +892,7 @@ msgstr "" "dass Verknüpfungen ignoriert werden. Ein negativer Wert bedeutet, dass alle " " Elemente ignoriert werden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. tags whose href matches will be ignored. Defaults " "to %default" @@ -351,15 +900,15 @@ msgstr "" "Ein regulärer Ausdruck. Elemente, deren Verknüpfungen ignoriert werden. " "Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Keine Links zum Inhaltsverzeichnis hinzufügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Automatische Erkennung von Kapiteln verhindern." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -367,20 +916,24 @@ msgstr "" "Der reguläre Ausdruck zur Ermittlung von Kapitelüberschriften. Es wird nach " "mit (h1) - (h6) angegebenen Überschriften gesucht. Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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

            tags, you would use \"h2,none,\". Default is %default" msgstr "" -"Erkenne einen Kapitelanfang anhand des Elements mit dem angegebenen " -"Attribut. Das Format dieser Option ist tagname regexp,attribute " -"name,attribute value regexp. Um zum Beispiel alle \"header\" (\"h\") " -"Elemente mit dem Attribut class=\"chapter\" anzugleich, müsste man \"h\\" -"d,class,chapter\" benutzen. Voreinstellung ist %default" +"Erkennt ein Kapitel, das mit einem Element mit dem angegebenen Attribut " +"beginnt. Das Format für diese Option ist tagname regexp,attribute " +"name,attribute value regexp. Um zum Beispiel alle heading tags zu treffen " +"die das Attribut class=\"chapter\" haben, verwenden Sie \"h\\" +"d,class,chapter\". Sie können das Attribut \"none\" setzen um nur die tag " +"names zu treffen. Wenn Sie zum Beispiel alle

            tags treffen wollen, " +"benutzen Sie \"h2,none,\". Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -399,14 +952,14 @@ msgstr "" "Umblättern der in der LRF Datei verlangsamt. Diese Einstellung wird " "ignoriert, wenn die aktuelle Seite nur wenige Elemente enthält." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Seitenumbruch erzwingen vor Elementen, deren Namen diesem regulären Ausdruck " "entsprechen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -419,16 +972,16 @@ msgstr "" "class=\"chapter\" anzupassen, verwenden Sie \"h\\d,class,chapter\". " "Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Die ermittelten Kapitel zum Inhaltsverzeichnis hinzufügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" "Baen HTML Dateien vorbearbeiten, um die erstellte LRF Datei zu verbessern." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -436,11 +989,11 @@ msgstr "" "Sie müssen diese Auswahl treffen, wenn sie Dateien, die von pdftohtml " "erstellt wurden, verarbeiten wollen, sonst schlägt die Konvertierung fehl." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Benutzen Sie diese Einstellung bei HTML Dateien von Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -454,27 +1007,27 @@ msgstr "" "angegeben: --serif-family \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "Serife Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "Serifenlose Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "Nichtproportionale Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Bei der weiteren Verarbeitung ausführlicher vorgehen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Zu LRS konvertieren" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -483,7 +1036,7 @@ msgstr "" "Benutzen Sie diese Einstellung, wenn sie an einem Rechner mit geringem " "Hauptspeicher arbeiten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -496,7 +1049,7 @@ msgstr "" "cp-1252. Eine andere gebräuchliche Alternative ist utf-8. In der " "Voreinstellung wird versucht, die Kodierung zu erraten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -515,34 +1068,38 @@ msgstr "" "ZIP Archive, indem es nach einem eBook im Archiv sucht.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Keine Datei zur Konvertierung angegeben." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "%s gerendert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "%s schlug fehl" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "" "Einstellungen zur Kontrolle der Konvertierung von Comic (CBR, CBZ) Dateien " "zu eBooks" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" "Titel für erstelltes eBook. In der Voreinstellung wird der Dateiname benutzt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" "Gibt den Autor in den Metadaten des erstellen eBooks an. Voreinstellung ist " "%default." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." @@ -550,34 +1107,58 @@ msgstr "" "Pfad zur ausgegebenen LRF Datei. Laut Voreinstellung wird die Datei im " "aktuellen Verzeichnis erstellt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -"Anzahl der Farben für die Bildkonvertierung in Graustufen. Voreinstellung: " -"%default" +"Anzahl der Farben für die Konvertierung von Graustufenbildern. " +"Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" "Deaktivieren der Normalisierung (verbessert den Kontrast) des Farbbereichs " "für Bilder. Voreinstellung: False" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" "Seitenverhältnis des Bildes beibehalten. Voreinstellung ist " "bildschirmfüllende Darstellung." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "Schärfen deaktivieren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "Bilder im Querformat nicht in zwei Bilder im Hochformat aufteilen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Seitenverhältnis beibehalten und Bild so skalieren, dass die Bildschirmhöhe " +"als Bildbreite in der Querformatansicht verwendet wird." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Benutzt für rechts-nach-links Publikationen wie Mangas. Querformatige Seiten " +"werden von rechts nach links in mehrere hochformatige Seiten unterteilt." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" +"Entkörnung einschalten. Reduziert die Körnigkeit. Kann die Bearbeitungszeit " +"stark verlängern." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." @@ -586,7 +1167,7 @@ msgstr "" "sortieren, sondern die Reihenfolge verwenden, in der sie zum Comic " "hinzugefügt wurden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" @@ -595,7 +1176,7 @@ msgstr "" "Die Voreinstellung ist der SONY PRS-500 mit einer Bildschirmgröße von " "584x754 Punkten. Wahlmöglichkeiten sind %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." @@ -603,28 +1184,28 @@ msgstr "" "Ausführlicher, hilfreich zur Fehlersuche. Kann mehrmals angegeben werden um " "eine größere Ausführlichkeit zu erreichen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "Fortschrittsbalken nicht anzeigen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +"Convert a comic in a CBZ or CBR file to an ebook. \n" msgstr "" "%prog [options] comic.cb[z|r]\n" "\n" -"Konvertiert ein Comic einer CBZ oder CBR Datei in ein LRF eBook. \n" +"Konvertiert ein Comic einer CBZ oder CBR Datei in ein eBook. \n" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:328 -msgid "Rendering comic pages..." -msgstr "Rendere Seiten des Comics..." - -#: /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:378 msgid "Output written to" msgstr "Ausgabe gespeichert unter" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Rendere Seiten des Comics..." + #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" "Usage: %prog [options] mybook.epub\n" @@ -637,7 +1218,7 @@ msgstr "" " \n" "%prog konvertiert dateiname.epub in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -649,24 +1230,24 @@ msgstr "" "\n" "%prog konvertiert dateiname.fb2 in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Gebe erstellte HTML auf stdout aus und beende das Programm." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "Erstellte HTML Dateien nach vollzogener LRF Konvertierung behalten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Einstellungen für feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Einstellungen für html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Abruf des Rezepts misslungen: " @@ -694,32 +1275,32 @@ msgstr "Verarbeite %s" msgid "\tConverting to BBeB..." msgstr "\tKonvertiere in BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Konnte Datei nicht analysieren: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%s ist eine leere Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "Fehlschlag bei der Analysierung von %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "Konnte Link %s nicht zu TOC hinzufügen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Konnte Bild %s nicht verarbeiten. Fehler: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "Konnte verschachteltes PNG %s nicht verarbeiten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -727,14 +1308,14 @@ msgstr "" "Konnte Bild nicht verarbeiten: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" "Ein Fehler trat während der Bearbeitung einer Tabelle auf: %s. " "Tabellenformat wird ignoriert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -742,11 +1323,11 @@ msgstr "" "Schlechte Tabelle:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "Tabelle enthält Zelle, die zu groß ist" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -754,19 +1335,19 @@ msgstr "" "Sichern Sie die Website %s zuerst als HTML Datei und benutzen Sie dann " "html2lrf mit der gespeicherten HTML Datei." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "Konnte Umschlagbild nicht lesen: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "Lesen nicht möglich von: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Verarbeitung der OPF Datei schlug fehl" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -784,7 +1365,7 @@ msgstr "" "lokale Dateien verweisen. Somit können Sie es verwenden,\n" "um einen ganzen Verzeichnisbaum von HTML Dateien zu konvertieren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -796,7 +1377,7 @@ msgstr "" "\n" "%prog konvertiert dateiname.lit in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -804,27 +1385,27 @@ msgstr "" "%prog dateiname.lrf\n" "Konvertiert eine LRF Datei in eine LRS (XML UTF-8 kodierte) Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Ausgabe LRS Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Analysieren LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Erstelle XML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS gespeichert in " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" msgstr "Thumbnail Datei konnte nicht gelesen werden:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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." @@ -832,16 +1413,16 @@ msgstr "" "%prog [options] datei.lrs\n" "Erstellt eine LRF Datei aus einer LRS Datei." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Pfad zur Zieldatei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "Ausführlicher fortfahren" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "Konvertierung von LRS zu LRS, hilfreich bei der Fehlersuche." @@ -864,7 +1445,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Geben Sie den Buchtitel an" @@ -881,7 +1462,7 @@ msgid "Set sort key for the author" msgstr "Sortierung nach Autor" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "Die Kategorie dieses Buches ... (Z. B.: Geschichte)" @@ -930,24 +1511,24 @@ msgstr "" "\n" "%prog konvertiert dateiname.mobi in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "" "Konnte pdftohtml nicht finden, überprüfen Sie, ob es in der PATH Variable " "angegeben ist" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " lässt das Kopieren von Text nicht zu." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" " ist ein PDF, das aus Bildern hergestellt wurde. Es wird aber nur die " "Konvertierung von aus Text aufgebauten PDF Dateien unterstützt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -959,7 +1540,7 @@ msgstr "" "\n" "%prog konvertiert dateiname.pdf in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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." @@ -967,15 +1548,15 @@ msgstr "" "Pfad zum Ausgabeverzeichnis, in dem die HTML Datei erstellt werden soll. " "Voreinstellung auf aktuelles Verzeichnis." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Noch ausführlicher!" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "Es muss eine einzelne PDF Datei angegeben werden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -987,7 +1568,15 @@ msgstr "" "\n" "%prog konvertiert dateiname.rtf in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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 "" +"Diese RTF Datei hat ein Feature, das calibre nicht unterstützt. Konvertieren " +"Sie es in HTML und konvertieren Sie es erneut." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:19 msgid "" "%prog [options] mybook.txt\n" "\n" @@ -999,25 +1588,35 @@ msgstr "" "\n" "%prog konvertiert dateiname.txt in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Gebe Autoren ein" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Gebe Kommentar ein" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" "Eine durch Kommata getrennte Liste von Etiketten, die angewendet werden " "sollen" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Benutzung:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "Benutzung: imp-meta file.imp" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Kein Dateiname angegeben." + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -1042,23 +1641,23 @@ msgstr "" "bei isbndb.com erstellt werden kann.\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "Die ISBN des Buches, für das Sie Metadaten abrufen möchten." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "Der Autor des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "Der Titel des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "Der Herausgeber des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1066,16 +1665,16 @@ msgstr "" "Konnte aufgrund zu hoher Serverlast kein Umschlagbild abrufen. Bitte " "versuchen Sie es später wieder." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " nicht gefunden." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "LibraryThing.com Server Fehler. Versuchen Sie es später." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1100,98 +1699,227 @@ msgstr "Umschlagbild gespeichert unter" msgid "Usage: pdf-meta file.pdf" msgstr "Benutzung: pdf-meta dateiname.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Kein Dateiname angegeben." +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "Benutzung: rb-meta file.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [options] dateiname.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "Original MOBI HTML gespeichert in" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Häufig benutzte Verzeichnisse" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" +"Periodisch heruntergeladenen Inhalt automatisch auf das Gerät übertragen" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" +"Das zu verwendende Format bei der Speicherung einzelner Dateie auf die " +"Festplatte" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Bestätigung vor dem Löschen" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "Schaltflächengröße der Symbolleiste" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Zeige Schaltflächenbeschriftung in der Symbolleiste" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Aufteilung des Hauptfensters" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Benachrichtigen, wenn eine neue Version verfügbar ist" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Benutze römische Ziffern für Seriennummerierung" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" +"Anzahl der Umschlagbilder, die im Cover-Ansicht Modus angezeit werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Voreinstellungen für Konvertierung zu LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Optionen für den LRF eBook Viewer" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Gerät ist nicht mehr verbunden." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Geräteinformationen erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Liste der Bücher auf dem Gerät erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Metadaten zum Gerät senden" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "%d Bücher auf das Gerät laden" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Bücher vom Gerät löschen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Bücher vom Gerät herunterladen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Buch auf dem Gerät ansehen" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Titel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Bemerkung" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Pfad" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formate" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Dialog" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TextLabel" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:65 +msgid "&Previous" +msgstr "&Vorangegangenes" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:66 +msgid "&Next" +msgstr "&Nächstes" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:40 msgid "Choose Format" msgstr "Format wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" msgstr "" "Voreinstellungen für die Konvertierung von Comics (CBR/CBZ Dateien) setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" msgstr "Einstellungen für das Konvertieren &s setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" msgstr "&Titel:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" msgstr "&Autor(en):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" msgstr "A&nzahl der Farben:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Profil:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" msgstr "&Normalisieren deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" msgstr "Verhältnis &beibehalten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" msgstr "&Schärfen deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" msgstr "&Querformat" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 -msgid "Dont so&rt" -msgstr "Nicht sortieren" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "Nicht so&rtieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "Von &rechts nach links" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +msgid "De&speckle" +msgstr "Ent&körnung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "&Weite" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:23 msgid "Basic" @@ -1201,53 +1929,60 @@ msgstr "Einfach" msgid "Advanced" msgstr "Erweitert" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "
            Must be a directory." -msgstr "
            Muss ein Verzeichnis sein." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Ortsangabe der Datenbank ungültig " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Ortsangabe der Datenbank ungültig" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "
            Must be a directory." +msgstr "
            Muss ein Verzeichnis sein." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Ortsangabe der Datenbank ungültig " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.
            Cannot write to " msgstr "Ortsangabe der Datenbank ungültig.
            Speichern nicht möglich " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "Komprimiere Datenbank. Das kann etwas dauern..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "Komprimiere Datenbank..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Konfiguration" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "Speicherort der Bücherdatenbank (&library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" +msgstr "" +"Speicher&ort der eBooks (Die eBooks werden in Verzeichnissen nach Autoren " +"sortiert gespeichert und die Metadaten werden in der Datei metadata.db " +"gespeichert)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Zu einem neuen Ort der Datenbank wechseln" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1255,43 +1990,43 @@ msgstr "Zu einem neuen Ort der Datenbank wechseln" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "&Römische Ziffern für Serien Nummerierung verwenden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" "A&nzahl der Umschlagbilder, die (nach einem Neustart) in der Cover-Ansicht " "angezeigt werden:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "Benachrichtigung anzeigen, wenn &neue Version verfügbar ist" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "Nach einer Bestätigung vor dem Löschen von Dateien fragen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "Format zur &Speicherung einer Datei:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "&Priorität der Konvertierungsaufträge:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "Voreinstellung für Zei&tüberschreitung bei Netzwerkverbindungen:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" @@ -1299,61 +2034,78 @@ msgstr "" "Voreinstellung der Zeitüberschreitung für Netzwerkabrufe festsetzen (Gilt " "immer dann, wenn aus dem Internet Informationen abgerufen werden sollen)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " Sekunden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "Sprache wäh&len (erfordert Neustart):" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "Das voreingestellte Ausgabeformat für eBook Konvertierungen." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "EPUB" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "&Ausgabeformat:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Groß" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Mittel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Klein" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "&Größe der Schaltflächen in der Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "Zeige &Text in Schaltflächen der Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "Si&chtbare Spalten in Bibliothek-Ansicht wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Häufig benutzte Verzeichnisse" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" "Ein Verzeichnis zur Liste der häufig genutzten Verzeichnisse hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" "Ein Verzeichnis von der Liste der häufig genutzten Verzeichnisse entfernen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Freier unbenutzter Festplattenspeicher der Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "Datenbank &komprimieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "&Meta-Daten aus dem Dateinamen" @@ -1361,10 +2113,366 @@ msgstr "&Meta-Daten aus dem Dateinamen" msgid "ERROR" msgstr "FEHLER" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "Auf einmal in EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "%s in EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Meta-Daten" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Look & Feel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Seiteneinrichtung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Ermittlung der Kapitel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" +"Geben Sie Metadaten wie Titel und Autor des Buches an.\n" +"\n" +"Metadaten werden sowohl in der Datenbank als auch in der erstellten EPUB " +"Datei aktualisiert." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" +"Passen Sie das Aussehen der erzeugten EPUB Datei durch die Angabe von Dingen " +"wie Schriftgrößen an." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" +"Geben Sie die Einstellungen für das Seitenlayout, z.B. die Ränder, an." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "Feineinstellung der Erkennung von Kapitel- und Absatzüberschriften." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "Wählen Sie das Umschlagbild für " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Lesen nicht möglich" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Sie haben nicht die nötigen Rechte, um diese Datei zu lesen: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Fehler beim Lesen der Datei" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "

            There was an error reading from file:
            " +msgstr "

            Es trat ein Fehler beim Lesen dieser Datei auf:
            " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " ist kein gültiges Bild" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Konvertierung nicht möglich" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "Dieses Buch hat keine Formate verfügbar" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Keine verfügbaren Formate" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" +"Kann %s nicht konvertieren, da dieses Buch nicht den bekannten Formaten " +"entspricht" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "Wählen Sie das Format, das in EPUB konvertiert werden soll" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "In EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Umschlagbild" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "&Umschlagbild ändern:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Nach Umschlagbild durchsuchen..." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Um&schlagbild der Quelldatei verwenden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Titel: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Titel dieses Buches ändern" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Autor(en): " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Autor dieses Buches ändern. Mehrere Autoren sollten durch Kommata getrennt " +"werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "So&rtierung nach Autor:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Herausgeber: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Herausgeber dieses Buches ändern" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "&Etiketten: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"

            They can be any words or phrases, separated by commas." +msgstr "" +"Etiketten klassifizieren das Buch. Besonders wichtig bei der Suche nach " +"Büchern.

            Sie können für Etiketten durch Kommata getrennte Wörter " +"oder Sätze verwenden." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Serien:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Liste der bekannten Serien. Sie können neue Serien hinzufügen." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Index der Serien." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Buch " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "En&codierung der Quelldatei:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "&CSS überschreiben" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "&Linker Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr " Punkt" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "&Rechter Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "&Oberer Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "&Unterer Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "Automatische Kapitel Erkennung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "&XPath:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +msgid "" +"\n" +"\n" +"

            You can control how " +"calibre detects chapters using a XPath expression. To learn how to use XPath " +"expressions see the XPath " +"tutorial

            " +msgstr "" +"\n" +"\n" +"

            Sie können kontrollieren, " +"wie calibre Kapitel erkennt, indem Sie einen XPath Ausdruck verwenden. Eine " +"Anleitung zur Benutzung von XPath Ausdrücken finden Sie im " +"englischsprachigen XPath " +"Tutorial

            " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375 +msgid "Chapter &mark:" +msgstr "Kapitel &Markierung:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "Automatisches &Inhaltsverzeichnis" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" +"Anzahl der Vernküpfungen, die zum Inhaltsverzeichnis hinzugefügt werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "Erkannte Kapitel &nicht zum Inhaltsverzeichnis hinzufügen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "Kapitel Grenzwer&t" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" +"&Verwendung des automatisch erstellten Inhaltsverzeichnisses erzwingen" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Autor(en)" @@ -1457,36 +2565,6 @@ msgstr "Aktive Aufträge" msgid "&Stop selected job" msgstr "Ausgewählten Auftrag &stoppen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Meta-Daten" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Look & Feel" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Seiteneinrichtung" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Ermittlung der Kapitel" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Keine verfügbaren Formate" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" -"Kann %s nicht konvertieren, da dieses Buch nicht den bekannten Formaten " -"entspricht" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Wählen Sie das Format, das zu LRF konvertiert werden soll" @@ -1496,33 +2574,10 @@ msgid "Convert %s to LRF" msgstr "Konvertiere %s in LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Voreinstellungen zur Konvertierung wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "Lesen nicht möglich" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "Sie haben nicht die nötigen Rechte, um diese Datei zu lesen: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Fehler beim Lesen der Datei" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "

            There was an error reading from file:
            " -msgstr "

            Es trat ein Fehler beim Lesen dieser Datei auf:
            " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " ist kein gültiges Bild" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1572,10 +2627,6 @@ msgstr "" "Seiteneinstellungen wie Ränder und die Bildschirmgröße des Zielgeräts " "angeben." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "Feineinstellung der Erkennung von Kapitel- und Absatzüberschriften." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "No help available" msgstr "Keine Hilfe verfügbar" @@ -1584,281 +2635,156 @@ msgstr "Keine Hilfe verfügbar" msgid "Bulk convert ebooks to LRF" msgstr "eBooks auf einmal zu LRF konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Zu LRF konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Kategorie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Auswahlmöglichkeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Umschlagbild" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "&Umschlagbild ändern:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Nach Umschlagbild durchsuchen..." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Um&schlagbild der Quelldatei verwenden" - -#: /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:263 -msgid "&Title: " -msgstr "&Titel: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Titel dieses Buches ändern" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Autor(en): " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Autor dieses Buches ändern. Mehrere Autoren sollten durch Kommata getrennt " -"werden" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "So&rtierung nach Autor:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Herausgeber: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Herausgeber dieses Buches ändern" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "&Etiketten: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"

            They can be any words or phrases, separated by commas." -msgstr "" -"Etiketten klassifizieren das Buch. Besonders wichtig bei der Suche nach " -"Büchern.

            Sie können für Etiketten durch Kommata getrennte Wörter " -"oder Sätze verwenden." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Serien:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Liste der bekannten Serien. Sie können neue Serien hinzufügen." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Index der Serien." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Buch " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Ausgangsschrift&größe:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " Punkt" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Eingebundene Schriften" -#: /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:531 msgid "&Serif:" msgstr "&Serif:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif:" -#: /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:533 msgid "&Monospace:" msgstr "&Monospace:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -msgstr "En&codierung der Quelldatei:" - -#: /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:535 msgid "Minimum &indent:" msgstr "E&inrücken mindestens:" -#: /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:537 msgid "&Word spacing:" msgstr "&Wortabstand:" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Automatische &Rotation von Bildern einschalten" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "&Leerzeilen zwischen Paragraphen einfügen" -#: /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:541 msgid "Ignore &tables" msgstr "&Tabellen ignorieren" -#: /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:542 msgid "Ignore &colors" msgstr "Farben nicht bea&chten" -#: /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:543 msgid "&Preprocess:" msgstr "&Vorbearbeiten:" -#: /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:544 msgid "Header" msgstr "Kopfzeile" -#: /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:545 msgid "&Show header" msgstr "Kopfzeile an&zeigen" -#: /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:546 msgid "&Header format:" msgstr "&Kopfzeilenformat:" -#: /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:547 msgid "Override
            CSS" msgstr "CSS
            überschreiben" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "&Linker Rand:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " Pixel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "&Rechter Rand:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "&Oberer Rand:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "&Unterer Rand:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "&Konvertiere Tabellen in Bilder (gut bei großen/komlexen Tabellen)" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "&Faktor der Textgröße in gerenderten Tabellen:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Auf Titel basierende Ermittlung" -#: /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:560 msgid "&Disable chapter detection" msgstr "Kapitel Ermittlung &deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "&Regulärer Ausdruck:" -#: /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:562 msgid "Add &chapters to table of contents" msgstr "&Kapitel zum Inhaltsverzeichnis hinzufügen" -#: /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:563 msgid "Don't add &links to the table of contents" msgstr "Keine &Links zum Inhaltsverzeichnis hinzufügen" -#: /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:564 msgid "Tag based detection" msgstr "Auf Etiketten basierende Ermittlung" -#: /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:565 msgid "&Page break before tag:" msgstr "&Seitenumbruch vor Element:" -#: /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:566 msgid "&Force page break before tag:" msgstr "Seitenumbruch vor Element &erzwingen:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Seitenumbruch vor &Attribut erzwingen:" -#: /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:568 msgid "Detect chapter &at tag:" msgstr "Erkenne K&apitel bei Element:" -#: /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:569 msgid "Help on item" msgstr "Hilfe für das jeweilige Objekt" -#: /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:570 msgid "" "\n" "\n" +"\n" "

            " @@ -1868,8 +2794,8 @@ msgstr "" "\n" +"\n" "

            " @@ -1879,17 +2805,17 @@ msgid "Edit Meta information" msgstr "Meta-Informationen bearbeiten" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Meta-Informationen" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "S&ortierung nach Autor: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1898,19 +2824,19 @@ msgstr "" "Dickens\" zum Beispiel als \"Dickens, Charles\"." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Bewertung:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Bewertung dieses Buches: 0-5 Sterne" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " Sterne" @@ -1920,8 +2846,8 @@ msgstr "&Etiketten hinzufügen: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Etiketten-Editor öffnen" @@ -1935,7 +2861,7 @@ msgstr "" "Durch Kommata getrennte Liste der Etiketten, die von den Büchern entfernt " "werden. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 msgid "" "

            Enter your username and password for LibraryThing.com.
            If you " "do not have one, you can register " @@ -1945,65 +2871,72 @@ msgstr "" "LibraryThing.com an.
            Insofern Sie dies nicht besitzen, können " "Sie sich kostenlos anmelden!

            " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover.
            " msgstr "Konnte kein Umschlagbild abrufen.
            " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "Konnte kein Umschlagbild abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "Kann kein Umschlagbild abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Sie müssen die ISBN für dieses Buch angeben." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Meta-Informationen bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "Tausche Autor und Titel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +msgid "" +"Automatically create the author sort entry based on the current author entry" +msgstr "" +"Atuomatisch den Eintrag für die Sortierung nach Autor basierend auf dem " +"aktuellen Autor erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 msgid "Remove unused series (Series that have no books)" msgstr "Unbenutzte Serien entfernen (Serien ohne Bücher)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Meta-Daten vom Server abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Verfügbare Formate" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Ein neues Format für dieses Buch zur Datenbank hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "Markierte Formate dieses Buches aus der Datenbank löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Umschlagbild vom Server abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" "Benutzername und/oder Passwort Ihres Kontos bei LibraryThing.com ändern" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Passwort ändern" @@ -2032,13 +2965,15 @@ msgid "Tag" msgstr "Etikett" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Serie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Format" @@ -2376,11 +3311,11 @@ msgstr "Regulärer Ausdruck Gruppenname (?P)" #: /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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "Kein Treffer" @@ -2413,103 +3348,102 @@ msgstr "Regulärer Ausdruck Gruppenname (?P<series_index>)" msgid "ISBN:" msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Auftrag" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Status" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Fortschritt" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "Laufzeit" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "Fehler" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "Unbekannter Auftrag" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "Fertig" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Fehler" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" msgstr "Abwarten und Tee trinken..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "Bei der Arbeit..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "Kann Auftrag nicht abbrechen" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." -msgstr "" -"Kann Aufträge nicht abbrechen, die mit dem Gerät kommunizieren, da dies zu " -"Datenverlust führen kann." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "Kann Aufträge, die mit dem Gerät kommunizieren, nicht abbrechen" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "Kann schon fertiggestellte Aufträge nicht abbrechen." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "Auftrag wird schon ausgeführt" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "Kann Auftrag auf Warteliste nicht abbrechen" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Keine" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Etiketten" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formate" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Buch <font face=\"serif\">%s</font> von %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "Doppelklick ermöglicht <b>Bearbeitung</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Größe (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Datum" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Bewertung" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Pfad" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Zeitstempel" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "Suche (Zur erweiterten Suche die Schaltfläche links klicken)" @@ -2529,15 +3463,15 @@ msgstr "Mit Trennstrich versehen" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "<b>Änderungen werden erst nach einem Neustart wirksam.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" msgstr " - LRF Vorschau" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "<b>Keine Treffer</b> für die Suchworte <i>%s</i> gefunden." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "Keine Treffer gefunden" @@ -2581,11 +3515,11 @@ msgstr "eBook öffnen" msgid "Configure" msgstr "Konfigurieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Fehler bei der Kommunikation mit dem Gerät" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" @@ -2593,42 +3527,42 @@ msgstr "" "<p>Hilfe gibt es online bei <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "<b>%s</b>: %s von <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "An Hauptspeicher senden" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "An Speicherkarte senden" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "und aus der Datenbank löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "Auf die Speicherkarte senden (Voreinstellung)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Meta-Daten einzeln bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Meta-Daten auf einmal bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "Bücher aus einem einzelnen Verzeichnis hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2636,7 +3570,7 @@ msgstr "" "Bücher rekursiv hinzufügen (Ein Buch pro Verzeichnis, setzt voraus, dass " "jede eBook Datei das gleiche Buch in einem unterschiedlichen Format enthält)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2644,61 +3578,75 @@ msgstr "" "Bücher rekursiv hinzufügen (Mehrere Bücher pro Verzeichnis, setzt voraus, " "dass jede eBook Datei ein anderes Buch enthält)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Auf Festplatte speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "Auf Festplatte in ein einziges Verzeichnis speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "Nur das %s Format auf Festplatte speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Vorschau" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "Spezielles Format ansehen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Einzeln konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Auf einmal konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" -msgstr "Voreinstellungen für die Konvertierung zu LRF Dateien setzen" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "Voreinstellung für Konvertierung eingeben" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "Voreinstellungen für die Konvertierung von Comics setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr " gefunden." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "Schlechter Datenbank Standort" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "Wählen Sie einen Speicherort für Ihre eBook Bibliothek." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "Migriere Datenbank" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "Gerät: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " gefunden." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "Angeschlossen: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "Gerätedatenbank ist beschädigt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2729,8 +3677,8 @@ msgstr "" " </ol>\n" " " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2738,60 +3686,60 @@ msgstr "" "<p>Es existieren bereits Bücher mit dem selben Titel in der Datenbank. " "Sollen die folgenden Bücher trotzdem hinzugefügt werden?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "Duplikate gefunden!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "Lade Bücher auf das Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Gerätespeicher voll" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>Es können keine Bücher mehr auf das Gerät geladen werden, da der " "Gerätespeicher voll ist " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "Bestätigen Sie das Löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "Sind Sie sicher, dass Sie diese %d Bücher löschen wollen?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "Lösche Bücher vom Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "Kann Metadaten nicht bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Keine Bücher ausgewählt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "Sende Bücher an das Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "Keine geeigneten Formate" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" @@ -2799,11 +3747,11 @@ msgstr "" "Die folgenden Bücher konnten nicht auf das Gerät geladen werden, da keine " "geeigneten Formate vorhanden sind:<br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "Speichern auf Festplatte nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" @@ -2811,95 +3759,60 @@ msgstr "" "<p>Die folgenden Bücher konnten nicht auf die Festplatte gespeichert werden, " "da das %s Format für sie nicht verfügbar ist:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "Konnte einige eBooks nicht speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "Nachrichten abrufen von " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "Rufe Nachrichten ab von " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "Nachrichten abgerufen. Übertragung ans Gerät läuft." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "Konvertierung nicht möglich" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "Starte Massenkonvertierung von %d Büchern" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "Konvertiere Buch %d von %d (%s)" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -msgid "" -"<p>Could not convert %d of %d books, because no suitable source format was " -"found.<ul>%s</ul>" -msgstr "" -"<p>Konnte %d von %d Büchern nicht konvertieren, da kein brauchbares " -"Ursprungsformat gefunden werden konnte.<ul>%s</ul>" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:843 -msgid "Could not convert some books" -msgstr "Konnte einige Bücher nicht konvertieren" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "Konvertiere Comic %d von %d (%s)" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "Buch konvertieren: " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "Comic konvertieren: " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Kein Buch ausgewählt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "Ansehen nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "Format zur Vorschau wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "%s hat keine verfügbaren Formate." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "Konfiguration nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "Konfiguration nicht möglich während Aufträge abgearbeitet werden." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "Kopiere Datenbank nach " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "Kopiere Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "Kopiere Bibliothek nach " + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "Ungültige Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2907,23 +3820,23 @@ msgstr "" "<p>Es existiert bereits eine ungültige Datenbank in %s, bitte löschen Sie " "diese, bevor sie die bestehende Datenbank verschieben.<br>Fehler: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "Konnte Datenbank nicht verschieben" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "Es ist keine weitere Information verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "Es ist keine weitere Information über Bücher auf dem Gerät verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Fehler in der Kommunikation zum Gerät" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2931,15 +3844,16 @@ msgstr "" "Es trat ein Fehler in der Kommunikation mit dem Gerät auf. Bitte entfernen " "und schließen Sie das Gerät wieder an und - oder starten Sie neu." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "Konvertierungsfehler" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "Datenbank existiert nicht" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." @@ -2947,7 +3861,11 @@ msgstr "" "Das Verzeichnis, in dem die Datenbank sein sollte: %s existiert nicht mehr. " "Bitte wählen Sie einen neuen Ort für die Datenbank aus." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "Wählen Sie einen neuen Speicherort für die Datenbank" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" @@ -2955,7 +3873,7 @@ msgstr "" "<span style=\"color:red; font-weight:bold\">Letzte Version: <a " "href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " @@ -2965,27 +3883,27 @@ msgstr "" "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">neuen Features</a> an. " "Möchten Sie die Download Seite besuchen?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "Neue Version verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "Erweiterte Suche" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Suche:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -2993,7 +3911,7 @@ msgstr "" "Liste der Bücher nach Titel oder Autor durchsuchen<br><br>Durch Leerzeichen " "getrennte Wörter werden mit \"UND\" verknüpft" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -3002,60 +3920,68 @@ msgstr "" "durchsuchen<br><br>Durch Leerzeichen getrennte Wörter werden mit \"UND\" " "verknüpft" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Quick Search löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "Übereinstimmung mit irgendeinem" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "Übereinstimmung mit allen" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Bücher hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Bücher entfernen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Meta-Informationen editieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "An Reader übertragen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Nachrichten abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "F" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "In eBooks umwandeln" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "C" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "V" @@ -3068,7 +3994,7 @@ msgstr "" "stderr). Hilfreich bei Fenstern in denen GUI Programme nicht über Output-" "Streams verfügen." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "FEHLER: Unbehandelte Ausnahme" @@ -3089,23 +4015,23 @@ msgstr "" msgid "Custom news sources" msgstr "Individuelle Nachrichtenquellen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Aufträge:" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "Ein Klick zeigt die aktiven Aufträge." -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "Klicken Sie, um die Bücher in der Cover-Ansicht zu durchsuchen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "Klicken Sie, um die Cover-Ansicht zu verlassen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" @@ -3113,19 +4039,71 @@ msgstr "" "<p>Die Cover-Ansicht ist gesperrt.<br>Der Import des Pictureflow Moduls " "schlug fehl:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "Klicken Sie, um die Bücher anhand von Etiketten zu durchsuchen" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "Autoren" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "Herausgeber" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "Buch konvertieren: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "Comic konvertieren: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Starte Massenkonvertierung von %d Büchern" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "Konvertiere Buch %d von %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" +"<p>Konnte %d von %d Büchern nicht konvertieren, da kein brauchbares " +"Ursprungsformat gefunden werden konnte.<ul>%s</ul>" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "Konnte einige Bücher nicht konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Nachrichten abrufen von " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" msgstr "Ungültiger regulärer Ausdruck" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" msgstr "Ungültiger regulärer Ausdruck: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Bibliothek" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3133,7 +4111,7 @@ msgstr "" "Reader\n" "%s verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3141,40 +4119,44 @@ msgstr "" "Karte\n" "%s verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "Ein Klick zeigt die Liste der auf dem Computer vorhandenen Bücher" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "" "Ein Klick zeigt die Liste der im Hauptspeicher des Geräts vorhandenen Bücher" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" "Ein Klick zeigt die Liste der auf der Speicherkarte des Geräts vorhandenen " "Bücher" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" -"Pfad zur Datenbank von calibre. Die Voreinstellung ist der in den " -"Einstellungen gespeicherte Pfad." +"Pfad zur calibre Bibliothek. Die Voreinstellung ist der in den Einstellungen " +"gespeicherte Pfad." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "Benutze Bibliothek in" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" "%prog list [options]\n" "\n" -"Listet die in der Datenbank von calibre verfügbaren Bücher auf. \n" +"Listet die vorhandenen Bücher in der calibre Datenbank auf.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3187,7 +4169,7 @@ msgstr "" "Verfügbare Felder: %s\n" "Voreinstellung: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" @@ -3197,11 +4179,11 @@ msgstr "" "Verfügbare Felder: %s\n" "Voreinstellung: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "Sortiere Ergebnisse in aufsteigender Reihenfolge" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 " @@ -3211,15 +4193,15 @@ msgstr "" "sehen Sie sich bitte die Dokumentation, die die Suche betrifft, im " "Benutzerhandbuch an. Voreinstellung ist, keine Filterung durchzuführen." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "Ungültige Felder. Verfügbare Felder:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "Ungültiges Sortierungs-Feld. Verfügbare Felder:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" @@ -3227,21 +4209,21 @@ msgstr "" "Die folgenden Bücher wurden nicht hinzugefügt, da sie schon in der Datenbank " "vorhanden sind (siehe --duplicates Option):" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" "%prog add [options] Datei1 Datei2 Datei3 ...\n" "\n" "Fügt die angegebenen Dateien als Bücher zur Datenbank hinzu. Sie können auch " -"Verzeichnisse angeben, sehen Sie sich dazu die zu den Verzeichnissen " -"gehörigen Optionen weiter unten an. \n" +"Verzeichnisse angeben, vergleichen\n" +"Sie dazu die auf Verzeichnisse bezogenen Optionen unten.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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" @@ -3250,11 +4232,11 @@ msgstr "" "und alle Dateien in diesem Verzeichnis sind verschiedene eBook Formate " "dieses einzelnen Buches" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "Verzeichnisse rekursiv verarbeiten" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." @@ -3262,12 +4244,12 @@ msgstr "" "Füge Bücher zur Datenbank hinzu, auch wenn diese schon vorhanden sind. Der " "Abgleich erfolgt aufgrund des Titels der Bücher." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" "Sie müssen wenigstens eine Datei auswählen, die hinzugefügt werden soll" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3282,11 +4264,11 @@ msgstr "" "(Sie erhalten die ID Zahlen durch die Benutzung des Befehls list). Zum " "Beispiel: 23,34,57-85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "Sie müssen wenigstens ein Buch auswählen, das entfernt werden soll" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3300,15 +4282,15 @@ msgstr "" "gekennzeichneten logischen Buches hinzu. Sie erhalten die ID durch den list " "Befehl. Falls das Format schon vorhanden ist, wird es ersetzt.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "Sie müssen eine ID und eine eBook Datei angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "eBook Datei muss eine Endung haben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3325,35 +4307,35 @@ msgstr "" "eine Dateiendung wie LRF oder TXT oder EPUB sein. Falls das logische Buch im " "entsprechenden Format nicht vorliegt, passiert gar nichts.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "Sie müssen eine ID und ein Format (Dateiendung) angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" "\n" -"%prog show_metadata [options] id\n" +"%prog show_metadata [options] ID\n" "\n" -"Zeige die in der calibre Datenbank gespeicherten Meta-Daten für das durch " -"die ID erkannte Buch. \n" -"\"id\" ist eine ID Nummer des Befehls \"list\". \n" +"Zeigt die in der calibre Datenbank gespeicherten Metadaten für das durch die " +"ID angegebene Buch.\n" +"ID ist eine ID Nummer des Befehls list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "Drucke Meta-Daten als OPF (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "Sie müssen eine ID angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3361,89 +4343,143 @@ msgid "" "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" +"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 "" "\n" -"%prog set_metadata [options] id /verzeichnis/zu/metadata.opf\n" +"%prog set_metadata [options] ID /pfad/zu/metadaten.opf\n" "\n" -"Übernehme die Meta-Daten, die in der calibre Datenbank für das durch die ID " -"erkannte Buch gespeichert werden,\n" -"aus der OPF Datei metadata.opf. \"id\" ist eine ID Nummer des Befehls " -"\"list\". Sie erhalten \n" -"einen Eindruck über das OPF Format, wenn Sie die --as-opf Option mit dem \n" -"Befehl show_metadata verwenden.\n" +"Stellt die in der calibre Datenbank gespeicherten Metadaten für das durch " +"die ID angegebene Buch\n" +"ein auf die Metadaten der OPF Datei metadata.opf. ID ist eine ID Nummer des " +"Befehls list. Sie\n" +"erhalten einen ersten Eindruck vom OPF Format durch die Verwendung der --as-" +"opf Option mit dem\n" +"show_metadata Befehl.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "Geben Sie eine ID und eine Meta-Daten Datei an" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" -"%prog export [options] ids \n" +"%prog export [options] IDs\n" "\n" -"Exportiert die durch IDs angegebenen Bücher (als durch Kommata getrennte " -"Liste) in das Dateisystem.\n" -"Der Export speichert alle Formate des Buches, sein Umschlagbild und die Meta-" -"Daten (in \n" -"einer OPF Datei). Sie erhalten ID Nummern mit dem Befehl \"list\". \n" +"Exportiert die durch IDs (eine durch Kommata getrennte Liste) angegebenen " +"Bücher in das Dateisystem.\n" +"Der Exportvorgang speichert alle Formate der Bücher, ihre Umschlagbilder und " +"Metadaten (in\n" +"einer opf Datei). Die ID Nummern erhalten Sie mit dem Befehl list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" "Exportiere alle Bücher der Datenbank, die Liste der IDs wird ignoriert." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "Exportiere Bücher in das angegebene Verzeichnis. Voreinstellung ist" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "Exportiere alle Bücher in ein einziges Verzeichnis" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" "Erstelle Dateinamen mit \"Autor - Titel\" anstelle von \"Titel - Autor\"" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "Sie müssen IDs oder die %s Option angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" "%%prog command [options] [arguments]\n" "\n" -"%%prog ist die Befehlszeilenschnittstelle zur Bücher Datenbank von calibre. " +"%%prog ist die Befehlszeilenschnittstelle zur calibre eBook Datenbank.\n" "\n" -"\n" -"command ist eines der folgenden:\n" +"command ist eines dieser Befehle:\n" " %s\n" -" \n" -"Für Hilfe zu einem bestimmten Befehl (command): %%prog command --help\n" +"\n" +"Sie erhalten Hilfe zu einem bestimmten Befehl mit: %%prog command --help\n" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "<p>Kopiere Bücher nach %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "Kopiere <b>%s</b>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "<p>Migriere alte Datenbank zu eBook Bibliothek in %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "Komprimiere Datenbank" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "Konnte Arbeitsprozess nicht starten." +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "Auftrag durch Benutzer unterbrochen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sBenutzung%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Erstellt von " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "Pfad zur Datenbank in der die Bücher gespeichtert sind" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "Verhaltensmuster zum Erraten der Metadaten aus den Dateinamen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "Zugangsschlüssel für isbndb.com" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" +"Voreinstellung der Zeitüberschreitung bei Netzwerkverbindungen (in Sekunden)" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "Pfad zum Verzeichnis, in dem die Bibliothek gespeichert ist" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "Sprache, in der die Benutzer-Oberfläche dargestellt wird" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "Konnte die fontconfig library nicht initialisieren" @@ -3474,7 +4510,153 @@ msgstr "Feed unbekannt" msgid "Untitled article" msgstr "Artikel ohne Titel" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" +"Einstellungen zur Kontrolle des Abrufs von regelmäßig erscheinendem Inhalt " +"aus dem Netz." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "Download-Engine anpassen" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Timeout in Sekunden beim Warten auf eine Antwort vom Server. Voreinstellung: " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Kleinstes Intervall in Sekunden zwischen aufeinander folgenden Abrufen. " +"Voreinstellung ist %default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"Zeichenkodierung für Webseiten, die zu laden versucht werden. In der " +"Voreinstellung wird versucht, die Kodierung zu erraten." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Nur Links, die diesem Regulären Ausdruck entsprechen, werden verfolgt. Diese " +"Option kann mehrmals angegeben werden, somit werden Links verfolgt, solange " +"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden alle " +"Links verfolgt." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Jeder Link, der diesem Regulären Ausdruck entspricht, wird ignoriert. Diese " +"Option kann mehrmals angegeben werden, somit werden Links ignoriert, solange " +"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden keine " +"Links ignoriert. Falls beide --filter-regexp und --match-regexp angegeben " +"sind, wird --filter-regexp zuerst angewendet." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Lade CSS Stylesheets nicht herunter." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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 "" +"Geben Sie eine Liste von Feeds zum Download an. Zum Beispiel: \n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"Wenn Sie diese Option wählen, wird jedes Argument %prog ignoriert und die " +"Voreinstellung zum Download der Feeds verwendet." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "Noch ausführlicher bei der weiteren Verarbeitung vorgehen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"Der Titel für dieses Rezept. Wird als Titel für alle eBooks benutzt, die aus " +"den geladenen Feeds erstellt wurden." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" +"Benutzername für Webseiten, die einen Login für den Inhaltsabruf benötigen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" +"Passwort für Webseiten, die einen Login für den Inhaltsabruf benötigen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Anzahl der Links in die Tiefe, die vom Feed aus verfolgt werden sollen. " +"Voreinstellung %default" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"Das Verzeichnis, in dem die geladenen Feeds gespeichert werden. " +"Voreinstellung auf das aktuelle Verzeichnis." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "Fortschrittsbalken nicht anzeigen" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "Sehr ausführliche Ausgabe, hilfreich bei der Fehlersuche." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Hilfreich zur Entwicklung von Rezepten. Erzwingt maximal 2 Artikel pro Feed " +"und lädt höchstens 2 Feeds." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3514,145 +4696,81 @@ msgstr "" "Verfügbare installierte Rezepte:\n" "%s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" "Einstellungen für web2disk (um von Feeds verlinkte Webseiten abzurufen)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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 "" -"Geben Sie eine Liste von Feeds zum Download an. Zum Beispiel: \n" -"\"['http://feeds.newsweek.com/newsweek/TopNews', " -"'http://feeds.newsweek.com/headlines/politics']\"\n" -"Wenn Sie diese Option wählen, wird jedes Argument %prog ignoriert und die " -"Voreinstellung zum Download der Feeds verwendet." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 -msgid "Be more verbose while processing." -msgstr "Noch ausführlicher bei der weiteren Verarbeitung vorgehen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -msgid "" -"The title for this recipe. Used as the title for any ebooks created from the " -"downloaded feeds." -msgstr "" -"Der Titel für dieses Rezept. Wird als Titel für alle eBooks benutzt, die aus " -"den geladenen Feeds erstellt wurden." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:47 -msgid "Username for sites that require a login to access content." -msgstr "" -"Benutzername für Webseiten, die einen Login für den Inhaltsabruf benötigen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" -"Passwort für Webseiten, die einen Login für den Inhaltsabruf benötigen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" -"Anzahl der Links in die Tiefe, die vom Feed aus verfolgt werden sollen. " -"Voreinstellung %default" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "" -"The directory in which to store the downloaded feeds. Defaults to the " -"current directory." -msgstr "" -"Das Verzeichnis, in dem die geladenen Feeds gespeichert werden. " -"Voreinstellung auf das aktuelle Verzeichnis." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "Fortschrittsbalken nicht anzeigen" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "Sehr ausführliche Ausgabe, hilfreich bei der Fehlersuche." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -msgid "" -"Useful for recipe development. Forces max_articles_per_feed to 2 and " -"downloads at most 2 feeds." -msgstr "" -"Hilfreich zur Entwicklung von Rezepten. Erzwingt maximal 2 Artikel pro Feed " -"und lädt höchstens 2 Feeds." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "Rufe Feeds ab..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "Nachrichtenquelle unbekannt" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "Download beendet" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "Der Download der folgenden Artikel schlug fehl:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr " von " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "Der Download von Teilen der folgenden Artikel schlug fehl:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "\tFehlgeschlagene Verknüpfungen:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" "Konnte Artikel nicht abrufen. Der erneute Start mit --debug zeigt mögliche " "Gründe an" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "Feeds der Index Seite erhalten" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "Versuche Umschlagbild zu laden..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "Starte Download von [%d Thread(s)]..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "Feeds wurden nach %s heruntergeladen" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "Konnte Umschlagbild nicht laden: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "Lade Umschlagbild von %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "Artikel ohne Titel" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" @@ -3662,23 +4780,23 @@ msgstr "" "Artikel %s von %s geladen\n" "%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "Artikel geladen: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "Laden der Artikel fehlgeschlagen: %s von %s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "Laden der Artikel schlug fehl: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "Rufe Feed ab" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" @@ -3688,21 +4806,13 @@ msgstr "" "\n" "URL ist z.B. http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" "Grundverzeichnis, in das die URL gespeichert wird. Voreinstellung ist " "%default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Timeout in Sekunden beim Warten auf eine Antwort vom Server. Voreinstellung: " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3710,7 +4820,7 @@ msgstr "" "Maximale Zahl von einbezogenen Ebenen, z.B. Tiefe der Links, die verfolgt " "werden. Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3718,51 +4828,6 @@ msgstr "" "Höchstzahl der Dateien, die geladen werden. Dies trifft nur auf Dateien aus " "<a href> Tags zu. Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Kleinstes Intervall in Sekunden zwischen aufeinander folgenden Abrufen. " -"Voreinstellung ist %default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -msgid "" -"The character encoding for the websites you are trying to download. The " -"default is to try and guess the encoding." -msgstr "" -"Zeichenkodierung für Webseiten, die zu laden versucht werden. In der " -"Voreinstellung wird versucht, die Kodierung zu erraten." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:400 -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 "" -"Nur Links, die diesem Regulären Ausdruck entsprechen, werden verfolgt. Diese " -"Option kann mehrmals angegeben werden, somit werden Links verfolgt, solange " -"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden alle " -"Links verfolgt." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 -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 "" -"Jeder Link, der diesem Regulären Ausdruck entspricht, wird ignoriert. Diese " -"Option kann mehrmals angegeben werden, somit werden Links ignoriert, solange " -"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden keine " -"Links ignoriert. Falls beide --filter-regexp und --match-regexp angegeben " -"sind, wird --filter-regexp zuerst angewendet." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "Lade CSS Stylesheets nicht herunter." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche." diff --git a/src/calibre/translations/el.po b/src/calibre/translations/el.po index e40222a49f..da6fbc636e 100644 --- a/src/calibre/translations/el.po +++ b/src/calibre/translations/el.po @@ -7,252 +7,520 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-06-24 07:23+0000\n" "Last-Translator: Thanos Petkakis <thanospet@gmail.com>\n" "Language-Team: Greek <el@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: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Δημιουργήθηκε απο τον " - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Άγνωστο" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 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:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Άγνωστο" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Εκδότης" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 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:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 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:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Προσθήκη επικεφαλίδας σε όλες τις σελίδες με τίτλο και συγγραφέα" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 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:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 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:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 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:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 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:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 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:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 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:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 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:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -263,12 +531,12 @@ msgid "" "has only a few elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -276,25 +544,25 @@ msgid "" "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 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:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -302,33 +570,33 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 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:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -336,7 +604,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -347,92 +615,114 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -441,7 +731,7 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -449,24 +739,24 @@ msgid "" "%prog converts mybook.fb2 to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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:24 +#: /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:22 +#: /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:24 +#: /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:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "" @@ -494,71 +784,71 @@ msgstr "" msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" 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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -569,7 +859,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -577,48 +867,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -636,7 +926,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "" @@ -653,7 +943,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:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "" @@ -692,20 +982,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -713,21 +1003,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -735,7 +1025,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -743,23 +1039,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -773,38 +1079,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -824,96 +1130,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /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:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -924,53 +1355,57 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -978,99 +1413,116 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1078,10 +1530,335 @@ msgstr "" msgid "ERROR" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "" @@ -1165,34 +1942,6 @@ msgstr "" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "" @@ -1202,33 +1951,10 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1267,10 +1993,6 @@ msgid "" "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "" @@ -1279,276 +2001,156 @@ msgstr "" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "" - -#: /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:264 -msgid "Change the title of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -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/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -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/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" 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:531 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" 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:533 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" 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:539 msgid "Enable auto &rotation of images" msgstr "" -#: /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:540 msgid "Insert &blank lines between paragraphs" 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:541 msgid "Ignore &tables" msgstr "" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" 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:544 msgid "Header" 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:545 msgid "&Show header" 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:546 msgid "&Header format:" 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:547 msgid "Override<br>CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "" -#: /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:560 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" 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:565 msgid "&Page break before tag:" 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:566 msgid "&Force page break before tag:" 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:567 msgid "Force page break before &attribute:" 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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" 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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1559,36 +2161,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 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:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr "" @@ -1598,8 +2200,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1611,71 +2213,76 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "" @@ -1704,13 +2311,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "" @@ -2017,11 +2626,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2054,101 +2663,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2168,15 +2778,15 @@ msgstr "" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "" @@ -2220,118 +2830,132 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 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:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 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:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2347,307 +2971,287 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 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:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 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:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 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:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 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:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 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:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 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:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2657,7 +3261,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2675,78 +3279,132 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2754,68 +3412,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2824,11 +3482,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2837,15 +3495,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2855,29 +3513,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2885,62 +3543,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Δημιουργήθηκε απο τον " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -2971,7 +3682,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -2992,210 +3817,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 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:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/translations/es.po b/src/calibre/translations/es.po index 5e244c9bcf..b49e2ac07c 100644 --- a/src/calibre/translations/es.po +++ b/src/calibre/translations/es.po @@ -10,14 +10,14 @@ msgid "" msgstr "" "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-07-27 19:27+0000\n" -"Last-Translator: S. Dorscht <Unknown>\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-23 01:19+0000\n" +"Last-Translator: betatron <frangb@gmail.com>\n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" #~ msgid "" @@ -66,9 +66,22 @@ msgstr "" #~ msgid "mybook.epub" #~ msgstr "milibro.epub" +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "&Ubicación de la base de datos (library1.db)" + #~ msgid "&Access Key;" #~ msgstr "Clave de &acceso;" +#~ msgid "" +#~ "Cannot kill jobs that are communicating with the device as this may cause " +#~ "data corruption." +#~ msgstr "" +#~ "No se pueden detener los trabajos que estan en comunicación con el " +#~ "dispositivo ya que pueden causar corrupción de datos" + +#~ msgid "Cannot kill already completed jobs." +#~ msgstr "No se pueden detener trabajos ya finalizados" + #~ msgid "Cannot kill waiting jobs." #~ msgstr "No se pueden detener trabajos en espera" @@ -152,13 +165,56 @@ msgstr "" #~ "font-weight:600;\">calibre</span>: %1 de <span style=\" font-" #~ "weight:600;\">Kovid Goyal</span> %2<br />%3</p></body></html>" -#, fuzzy +#~ msgid "Copying database to " +#~ msgstr "Copiando base de datos a " + #~ msgid "" -#~ "Save the text below into a file named recipe.py and send the file to your " -#~ "friends, to allow them to use this recipe." +#~ "Path to the calibre database. Default is to use the path stored in the " +#~ "settings." #~ msgstr "" -#~ "Guardar el texto de abajo en el archivo recipe.py y enviarlo a un amigo para " -#~ "permitirle también a él usar esta receta." +#~ "Camino a la base de datos calibre. El valor predeterminado es a usar la ruta " +#~ "almacenada en la configuración." + +#~ msgid "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "List the books available in the calibre database. \n" +#~ msgstr "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "Mostrar los libros disponibles en la base de datos calibre. \n" + +#~ 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 "" +#~ "%prog add [options] file1 file2 file3 ...\n" +#~ "\n" +#~ "Añadir los archivos especificados como libros a la base de datos. También " +#~ "puede especificar\n" +#~ "directorios, consulte las opciones relacionadas a los directorios más abajo. " +#~ "\n" + +#~ 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 "" +#~ "%%prog command [opciones] [argumentos]\n" +#~ "\n" +#~ "%%prog es la interfaz en linea de comandos a la base de datos de libros de " +#~ "calibre\n" +#~ "\n" +#~ "command es uno de:\n" +#~ "%s\n" #~ msgid "" #~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " @@ -166,8 +222,8 @@ msgstr "" #~ "<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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -177,53 +233,406 @@ msgstr "" #~ "<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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sUso%s: %s\n" +#~ 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 "" +#~ "\n" +#~ "%prog show_metadata [options] id\n" +#~ "Muestra los metadatos almacenados en la Base de Datos de calibre para el " +#~ "libro identificado por ID.\n" +#~ "Id es un número de identificador de la lista de comandos. \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Creado por " +#~ 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 "" +#~ "\n" +#~ "%prog set_metadata [opciones] id /ruta/de/metadata.opf\n" +#~ "\n" +#~ "Establece los metadatos almacenados en la base de datos de calibre para el " +#~ "libro\n" +#~ "identificado por el número id, a partir de archivo OPF de metadatos " +#~ "\"metadata.opf\".\n" +#~ "Puede obtener información del formato OPF usando el modificador --as-opf en " +#~ "el \n" +#~ "comando show_metadata.\n" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ 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 "" +#~ "%prog export [opciones] ids \n" +#~ "\n" +#~ "Exporta los libros indicado por ids (una lista separada por comas) al " +#~ "sistema de archivos. \n" +#~ "Esta operación de exportación guardará todos los formatos del libro, la " +#~ "portada y los metadatos \n" +#~ "(en un archivo opf). Puede obtener los numeros id a partir del comando list. " +#~ "\n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "No se ha podido detectar la unidad de disco %s. Trate de reiniciar." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "El lector no tiene ninguna tarjeta de almacenamiento conectada" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Opciones a controlar la conversión a EPUB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"El archivo EPUB de salida. Si no es especificado, es derivado de el nombre " +"del archivo de entrada." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "Control de auto-detección de estructura de documento." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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 "" +"Control de la creación automática de la Tabla de Contenidos. Si se detecta " +"un archivo OPF\n" +"y éste tiene definida una Tabla de Contenidos, se usará dicha tabla en lugar " +"de intentar\n" +"generar una nueva.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "No añadir los capitulos autodetectados a la Tabla de Contenidos" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Desconocido" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 "" +"Convertir un archivo HTML a ebook en formato EPUB. Seguir los enlaces del " +"archivo HTML de manera recursiva.\n" +"Si especifica un archivo OPF en lugar de un archivo HTML, la lista de " +"enlaces se tomará del elemento\n" +"<spine> en el archivo OPF \n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "Debe especificar un archivo HTML de entrada." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "Escribir el HTML procesado en " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "El directorio de Salida. Por defecto es el directorio actual." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" +"Codificación de carácter para archivos HTML. Por defecto a auto detectar." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Crear la salida en un archivo zip. Si esta opción es especificada, el --" +"output debería ser el nombre del archivo y no del directorio." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Control del seguimiento de enlaces en archivos HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Número máximo de niveles de recursión al seguir enlaces en archivos HTML. " +"Debe ser un numero no-negativo. 0 implica que no se seguirá ningún enlace en " +"el archivo HTML raiz." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Establecer metadata del documento generado." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Establecer el titulo. Por defecto es autodetectado." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "El autor/es de este libro, mediante una lista separada por comas." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Utiles opciones para depurar." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "%prog [options] LITFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "Directorio de salida. Por defecto es el directorio actual" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Útil para depuración." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "Ebook OEB creado en" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Establecer título. Por defecto: nombre_del_archivo" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -231,49 +640,34 @@ msgstr "" "Establecer autor(es). Si indica más de un autor, sepárelos mediante comas. " "Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Desconocido" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Insertar comentarios." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Seleccione categorí­a." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Clave de orden por tí­tulo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Clave de orden para el autor" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Editorial" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Ruta al archivo de imagen a utilizar como portada" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -281,12 +675,12 @@ msgstr "" "Si se detecta un gráfico para la portada en el archivo de origen, utilizarla " "en lugar de la portada especificada." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" "Nombre del archivo de destino­. Por defecto, deriva del archivo de entrada" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -294,7 +688,7 @@ msgstr "" "Renderizar las tablas HTML como bloques de texto en lugar de las tablas " "actuales. Activar si el archivo HTML contiene tablas muy grandes o complejas." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -305,25 +699,25 @@ msgstr "" "y prioriza sobre ella en el caso de que esté asignada. Para usar --font-" "delta, iguale ésta variable a 0. Configuración por defecto: %defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Activa la rotación automática de imágenes más grandes que el ancho de la " "pantalla." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "Fija el espacio entre palabras en puntos. Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Separa los párrafos mediante líneas en blanco." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Añadir el encabezado en todas las páginas, poniendo tí­tulo y autor." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -331,7 +725,7 @@ msgstr "" "Establece el formato del encabezado. %a se reemplaza por el autor y %t por " "el tí­tulo. Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -339,7 +733,7 @@ msgstr "" "Substituye la hoja CSS. Se admite tanto una ruta al archivo CSS alternativo, " "como una cadena. En el último caso, la cadena se interpreta como CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -349,7 +743,7 @@ msgstr "" "que se añaden los archivos HTML al LRF. El archivo .opf debe estar en la " "misma carpeta que el archivo HTML base." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -357,7 +751,7 @@ msgstr "" "Sangrado mínimo para párrafos (el sangrado de la primera línea de cada " "párrafo) en ptos. Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -367,7 +761,7 @@ msgstr "" "lí­nea en FONT_DELTA puntos. FONT_DELTA puede ser una fracción. Si es un " "valor negativo, el tamaño de la fuente disminuye." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." @@ -375,7 +769,7 @@ msgstr "" "Generar todo el contenido en negro sobre blanco en lugar de los colores " "indicados por el HTML o CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -385,23 +779,23 @@ msgstr "" "determina, entre otras cosas, la resolución y el tamaño de la pantalla del " "dispositivo. Por defecto: %s Perfiles soportados: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Margen izquierdo de la página. Por defecto: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Margen derecho de la página. Por defecto: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Margen superior de la página. Por defecto: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Margen inferior de la página. Por defecto: %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -409,7 +803,7 @@ msgstr "" "Renderizar las tablas en documentos html como imágenes (Muy útil si el " "documento consta de tablas grandes o complejas." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -417,7 +811,7 @@ msgstr "" "Multiplicar el tamaño del texto en las tablas renderizadas por éste factor. " "Por defecto es: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -426,7 +820,7 @@ msgstr "" "Número máximo de niveles para procesar enlaces recursivamente. El valor 0 " "(cero) indica que no se seguirán. Un valor negativo, ignora las marcas <a>." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -434,15 +828,15 @@ msgstr "" "Una expresión regular. Las etiquetas <a> cuyos atributos href coincidan " "serán ignoradas. Por defecto es %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "No incluir enlaces en el índice de contenidos" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Impedir la detección automática de capítulos." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -450,20 +844,17 @@ msgstr "" "Expressión regular utilizada para detectar los títulos de los capítulos. " "Busca las marcas de encabezado (h1-h6). Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" -"Detectar el comienzo de un capítulo en un elemento que contenga el atributo " -"especificado. El formato para ésta espresión es tagname regexp, nombre del " -"atributo, valor del atributo regexp. Por ejemplo, para encontrar todas las " -"etiquetas de cabecera que tienen como attribute class=\"capítulo\" podría " -"usar: \"h\\d,class,capítulo\". El valor por defecto es: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -481,14 +872,14 @@ msgstr "" "cambio de página en el archivo LRF. Esta opción se ignora si la página " "actual tiene pocos elementos." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Forzar un salto de página previo a las etiquetas cuyos nombres coincidan con " "esta expresión regular." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -500,16 +891,16 @@ msgstr "" "ejemplo, \"h\\d,class,chapter\", coincide con todas las marcas de encabezado " "que tienen el atributo class=\"chapter\". Por defecto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Incluir capítulos detectados en el índice de contenidos." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" "Preprocesa los archivos Baen HTML para mejorar el archivo LRF generado." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -517,11 +908,11 @@ msgstr "" "Es necesario activar esta opción para archivos generados con pdftohtml, para " "evitar que la conversión falle." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Utilice esta opción para archivos html0 de Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -534,27 +925,27 @@ msgstr "" "-serif-family \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "Familia de fuentes serif per a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "Familia de fuentes sans-serif a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "Familia de fuentes monoespaiadas a incrustar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Ser prolijo al procesar" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Convertir a LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -562,7 +953,7 @@ msgstr "" "Minimizar el uso de memoria, a cambio de mayor tiempo de procesador. Usar " "esta opción si el equipo no dispone de mucha RAM." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -575,7 +966,7 @@ msgstr "" "es cp-1252. Otra opción habitual es utf-8. La opción por defecto es intentar " "adivinar la codificación." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -588,91 +979,136 @@ msgstr "" "any2lrf [optiones] miarchivo\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "No se ha especificado ningun fichero para convertir" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "Fallido %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "" +"Opciones a controlar la conversión de archivos cómicas(CBR, CBZ) en " +"documentos." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" +"Titulo para documento generado. Por defecto es a usar el nombre de archivo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" +"Establece el autor en el metadato del ebook generado. Por defecto es %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" +"Ruta para el archivo de salida LRF. Por defecto un archivo es creado en el " +"directorio actual." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" +"Número de colores para conversión de imágenes a escala de grises. Por " +"defecto es %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" +"Deshabilitar normalizar(mejorar contraste) rango de color para imágenes. Por " +"defecto: False" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" +"Mantener relación de aspecto de la imagen. El valor por defecto es para " +"rellenar la pantalla." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." -msgstr "" +msgstr "Deshabilitar afilar." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" +msgstr "No dividir imágenes apaisadas en dos imágenes verticales" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Mantener la proporción en el tamaño de la imagen, usando la altura de la " +"pantalla como ancho de imagen en el modo de visualización apaisado." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Usado para publicaciones de derecha a izquierda como Mangas. Causa formatear " +"paginas a ser divididas en paginas vertical de derecha a izquierda." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." msgstr "" +"No sortear los archivos encontrados en el comic por nombre alfabético. En " +"vez usar el orden en el que fueron agregados al comic." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" +"Escoger el perfil para el cual se está generando este LRF. Por defecto es el " +"SONY PRS-500 con un tamaño de pantalla de 584x754 píxeles. Las opciones son " +"%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." msgstr "" +"Información y mensajes más descriptivos. Útil para depuración de errores. Se " +"puede especificar varias veces para mayor descriptividad." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." -msgstr "" +msgstr "No mostar barra de progreso." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" -msgstr "" +msgstr "Salida escrita a" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Interpretando paginas comic..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" @@ -686,7 +1122,7 @@ msgstr "" " \n" "%prog converte mybook.epub a mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -698,25 +1134,25 @@ msgstr "" "\n" "%prog converte mybook.fb2 a mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Imprimir el HTML generado por la salida estándar y salir." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "" "Guardar archivos generados HTML después de completar la conversión a la LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Opciones para controlar el comportamiento de feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Opciones para controlar el comportamiento de html2rtf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Obtención fallida de la receta: " @@ -744,32 +1180,32 @@ msgstr "Procesando %s" msgid "\tConverting to BBeB..." msgstr "\tConversión a BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "No se pudo analizar el archivo: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%s es un archivo vacío" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "No se pudo analizar el enlace %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "No se puedo añadir el enlac %s al TOC" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Incapaz de procesar imagen %s. Error: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "Incapaz de procesar PNG entrelazado %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -777,14 +1213,14 @@ msgstr "" "No se puedo procesar imagen: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" "Ocurrió un error al procesar la tabla: %s. Se ignora la identificación de la " "tabla." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -792,11 +1228,11 @@ msgstr "" "Tabla errónea:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "La tabla contiene una celda demasiado larga" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -804,19 +1240,19 @@ msgstr "" "Primero debe guardar la página web %s como un archivo html y después " "ejecutar html2rtf sobre él." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "No se puedo leer la imagen de portada: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "No se puedo leer de: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Incapaz de procesar el archivo opf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -835,7 +1271,7 @@ msgstr "" "De esta forma, puede usarlo para convertir un \n" "árbol completo de archivos HTML." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -847,7 +1283,7 @@ msgstr "" "\n" "%prog convierte milibro.lit en milibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -855,27 +1291,27 @@ msgstr "" "%prog libro.lrf\n" "Convierte un archivo LRF en un archivo LRS (XML codificado en UTF-8)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Archivo LRS de salida" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Analizando LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Creando XML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS escrito en " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" msgstr "No se pudo leer el archivo de miniatura:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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." @@ -883,16 +1319,16 @@ msgstr "" "%prog [opciones] archivo.lrs\n" "Compila un archivo LRS a un archivo LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Directorio del archivo de salida" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "Procesado detallado" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "Convierte LRS a LRS, útil para depuración." @@ -915,7 +1351,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Insertar el nombre del libro" @@ -932,7 +1368,7 @@ msgid "Set sort key for the author" msgstr "Insertar la clave de orden por autor" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "Categoria a la que pertenece el libro. Por ejemplo, Historia" @@ -978,20 +1414,20 @@ msgstr "" "\n" "%prog convierte milibro.mobi en milibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "No fué posible encontrar pdftohtml, compruebe que está en el PATH" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " no permite copiar texto." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 " es un PDF con imágenes. Sólo son válidos PDFs con texto." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -1003,7 +1439,7 @@ msgstr "" "\n" "%prog convierte milibro.pdf en milibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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." @@ -1011,15 +1447,15 @@ msgstr "" "Directorio de salida en donde crear el archivo HTML. Por defecto es el " "directorio actual." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Más detallado." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "Debe seleccionar un único archivo PDF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -1031,7 +1467,13 @@ msgstr "" "\n" "%prog convierte milibro.rtf en milibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -1043,23 +1485,33 @@ msgstr "" "\n" "%prog convierte milibro.txt en milibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Introduzca los autores" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Vea el comentario" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" -msgstr "" +msgstr "Lista de etiquetas separada por comas que desea establecer" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Uso:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "Uso: imp-meta file.imp" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Nombre de archivo sin especificar." + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -1081,23 +1533,23 @@ msgstr "" "gratuita en isbndb.com\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "El ID de ISBN del libro del cual desea los metadatos." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "El autor cuyos libros queremos buscar." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "El título del libro que busca." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "El editor del libro que busca." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1105,16 +1557,16 @@ msgstr "" "No se pudo obtener la portada debido a que el servidor sufre una carga " "excesiva. Por favor, inténtelo de nuevo más tarde." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " no encontrado." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "Error del servidor LibraryThing.com. Pruebe de nuevo más tarde." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1139,97 +1591,224 @@ msgstr "Portada guardada en" msgid "Usage: pdf-meta file.pdf" msgstr "Uso: pdf-meta archivo.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Nombre de archivo sin especificar." +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "Uso: rb-meta file.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [opciones] miebook.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "HTML MOBI en bruto guardado en" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Directorios usados con frecuencia" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" +"Enviar contenido descargado periodicamente al dispositivo automaticamente" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "El formato a usar al guardar archivos al disco" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Confirmar antes de borrar" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "Tamaño de iconos de barra de herramientas" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Mostrar etiquetas de botones en la barra de herramientas" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Ventana principal geometrica" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Notificar cuando una versión esta disponible" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Usar numeros Romanos para numero de series" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" +"Numero de portadas de libros a mostrar en el modo de navegación de portadas." + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Opciones por defecto para conversión a LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Opciones para el visor de documento LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Dispositivo no esta conectado." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Obtener información de dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Obtener lista de libros en dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Enviar metadata al dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "Cargar %d libros al dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Borrar libros del dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Descargar libros del dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Ver libro en dispositvo" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Título" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Comentarios" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Ruta" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formatos" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Diálogo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TextLabel" +#: /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 "Elegir formato" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" -msgstr "" +msgstr "Opciones por defecto para conversión de comics (archivos CBR/CBZ)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" -msgstr "" +msgstr "Establecer opciones para convertir %s" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" -msgstr "" +msgstr "&Título:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" -msgstr "" +msgstr "&Autor(es)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" -msgstr "" +msgstr "&Numeros de Colores" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Perfil:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" -msgstr "" +msgstr "Desactivar &normalización" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" -msgstr "" +msgstr "Mantener &proporción" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /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:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" +msgstr "&Apaisado" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "No ordenar" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "&Derecha a izquierda" + +#: /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:88 -msgid "Dont so&rt" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "&Ancho" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:23 msgid "Basic" @@ -1239,53 +1818,59 @@ msgstr "Básico" msgid "Advanced" msgstr "Avanzada" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "<br>Debe ser un directorio." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Ubicación no válida " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Ubicación no válida" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Debe ser un directorio." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Ubicación no válida " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "Ubicación no válida.<br>Imposible escribir en " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "Compactando base de datos. Esto podría durar un rato" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "Compactando..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Configuración" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "&Ubicación de la base de datos (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" +msgstr "" +"Emplazamiento de los ebooks (Los ebooks son almacenados en carpetas " +"ordenadas por autor, los metadatos se almacenan en el archivo metadata.db)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Navegar a la nueva ubicación de la base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1293,41 +1878,41 @@ msgstr "Navegar a la nueva ubicación de la base de datos" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "Uso de numerales &romanos para números de serie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "Mostrar aviso cuando una &nueva versión esté disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" -msgstr "" +msgstr "Solicitar &confirmación antes de eliminar archivos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "Formato al guardar un &único archivo:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "&Prioridad para los trabajos de conversión:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "&timeout por defecto de la red:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" @@ -1335,59 +1920,76 @@ msgstr "" "Establecer el tiempo de espera maximo para peticiones de red (cuando " "conectamos a internet para adquirir alguna información)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " segundos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "Seleccionar idioma (requiere reiniciar el programa)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Barra de herramientas" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Grande" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Medio" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Pequeño" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "Tamaño de &botón en la barra de herramientas" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "Mostrar &texto en los botones de la barra de herramientas" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "Seleccione las &columnas visibles en la vista de biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Directorios usados con frecuencia" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "Añadir directorio a la lista de directorios frecuentes" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "Eliminar directorio a la lista de directorios frecuentes" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Espacio de disco disponible de la base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "&Compactar base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "&Metadatos a partir del nombre de archivo" @@ -1395,10 +1997,339 @@ msgstr "&Metadatos a partir del nombre de archivo" msgid "ERROR" msgstr "ERROR" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Metadatos" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Apariencia" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Configuración de página" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Detección de capítulos" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "Afinar la detección de capítulos y secciones." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "No se puede leer" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "No tienes permiso de lectura en el archivo: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Error leyendo archivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Hubo un error leyendo el archivo: <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " no es una imagen válida" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "No se puede convertir" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Formatos no disponibles" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "No se puede convertir %s porque el formato no está soportado" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Portada" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "Cambia la imagen de &portada:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Localizar una imagen a utilizar como portada de este libro." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Usar portada del archivo &fuente" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Título: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Cambiar el título del libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Autor(es): " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Cambia el(los) autor(es). Para especificar más de uno, sepárelos mediante " +"comas." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "O&rd&en por autor:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Editorial: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Cambia la editorial del libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "Etique&tas: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" +"Etiquetas para categorizar el libr (muy útil en búsquedas). <br><br>Puede " +"utilizarse qualquier palabra o frase, separada medante comas." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Series:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Listado de series conocidas. Se puede añadir nuevas series." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Índice de serie." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Libro " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "&Codificación de la fuente:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "Margen &Izquierdo:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "Margen &Derecho:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "Margen &Superior:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "Margen &Inferior:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Autor(es)" @@ -1486,34 +2417,6 @@ msgstr "Trebajos activos" msgid "&Stop selected job" msgstr "&Detener trabajo seleccionado" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Metadatos" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Apariencia" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Configuración de página" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Detección de capítulos" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Formatos no disponibles" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "No se puede convertir %s porque el formato no está soportado" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Elegir el formato a conertir en LRF" @@ -1523,33 +2426,10 @@ msgid "Convert %s to LRF" msgstr "Convertir %s a LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Fijar valores de conversión por defecto" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "No se puede leer" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "No tienes permiso de lectura en el archivo: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Error leyendo archivo" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "<p>Hubo un error leyendo el archivo: <br /><b>" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " no es una imagen válida" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1596,10 +2476,6 @@ msgid "" msgstr "" "Configuración de página del dispositivo: márgenes y tamaño de la pantalla" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "Afinar la detección de capítulos y secciones." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">Ayuda no disponible</font>" @@ -1608,281 +2484,157 @@ msgstr "<font color=\"gray\">Ayuda no disponible</font>" msgid "Bulk convert ebooks to LRF" msgstr "Convertir ebooks a LRF en masa" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Convertir a LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Categoría" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Opciones" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Portada" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "Cambia la imagen de &portada:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Localizar una imagen a utilizar como portada de este libro." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Usar portada del archivo &fuente" - -#: /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:263 -msgid "&Title: " -msgstr "&Título: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Cambiar el título del libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Autor(es): " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Cambia el(los) autor(es). Para especificar más de uno, sepárelos mediante " -"comas." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "O&rd&en por autor:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Editorial: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Cambia la editorial del libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "Etique&tas: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"<br><br>They can be any words or phrases, separated by commas." -msgstr "" -"Etiquetas para categorizar el libr (muy útil en búsquedas). <br><br>Puede " -"utilizarse qualquier palabra o frase, separada medante comas." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Series:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Listado de series conocidas. Se puede añadir nuevas series." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Índice de serie." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Libro " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Tamaño de la &fuente base:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " puntos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Fuentes incrustadas" -#: /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:531 msgid "&Serif:" msgstr "&Serif:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif:" -#: /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:533 msgid "&Monospace:" msgstr "&Monospace:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -msgstr "&Codificación de la fuente:" - -#: /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:535 msgid "Minimum &indent:" msgstr "&Sangrado mínimo:" -#: /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:537 msgid "&Word spacing:" msgstr "&Espaciado de palabras:" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Activa la &rotación automática de imágenes" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "Inserta líneas en &blanco entre párrafos" -#: /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:541 msgid "Ignore &tables" msgstr "Ignora las &tablas" -#: /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:542 msgid "Ignore &colors" msgstr "Ignorar &colores" -#: /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:543 msgid "&Preprocess:" msgstr "&Preprocesamiento:" -#: /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:544 msgid "Header" msgstr "Encabezado" -#: /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:545 msgid "&Show header" msgstr "&Mostrar encabezado" -#: /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:546 msgid "&Header format:" msgstr "&Formato del encabezado:" -#: /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:547 msgid "Override<br>CSS" msgstr "Substituye<br>CSS" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "Margen &Izquierdo:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " Píxeles" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "Margen &Derecho:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "Margen &Superior:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "Margen &Inferior:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" "&Convertir las tablas a imágenes (bueno para tablas grandes y complejas)" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "&Multiplicador para tamaño del texto en las tablas renderizadas." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Detección basada en el título" -#: /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:560 msgid "&Disable chapter detection" msgstr "&Desactivar detección de capítulos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "Expresión &Regular:" -#: /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:562 msgid "Add &chapters to table of contents" msgstr "Añadir &capítulos a la tabla de contenidos" -#: /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:563 msgid "Don't add &links to the table of contents" msgstr "No añada &enlaces a la tabla de contenidos" -#: /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:564 msgid "Tag based detection" msgstr "Detección basada en etiquetas" -#: /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:565 msgid "&Page break before tag:" msgstr "Inserta un salto de &página delante de la marca:" -#: /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:566 msgid "&Force page break before tag:" msgstr "&Fuerza un salto de página delante de la marca:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Fuerza un salto de página delante del &atributo:" -#: /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:568 msgid "Detect chapter &at tag:" msgstr "Detectar Capítulo &at tag:" -#: /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:569 msgid "Help on item" msgstr "Ayuda con el ítem" -#: /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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1892,8 +2644,8 @@ msgstr "" "<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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1903,17 +2655,17 @@ msgid "Edit Meta information" msgstr "Editar Meta-información" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Meta-información" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "&Ordenar autores: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1922,19 +2674,19 @@ msgstr "" "Federico García Lorca como Lorca, Federico" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Valoración:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Valora este libro: 0-5 estrellas" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " estrellas" @@ -1944,8 +2696,8 @@ msgstr "Aña&dir las etiquetas: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Abrir editor de etiquetas" @@ -1957,7 +2709,7 @@ msgstr "&Quitar etiquetas" msgid "Comma separated list of tags to remove from the books. " msgstr "Lista de etiquetas separadas por comas para eliminar de los libros " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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> " @@ -1967,67 +2719,72 @@ msgstr "" "<b>LibraryThing.com</b>. <br/>Si no dispone de una cuenta, puede <a " "href='http://www.librarything.com'>regisrarse</a> de manera gratuita.</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "<b>No se puede descargar la portada.</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "No se puede descargar la portada." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "No se puede descargar la portada" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Especifique primero un ISBN válido para el libro." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Editar meta-información" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" "Eliminar series que no están en uso (series que no tienen ningún libro " "asociado)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Buscar metadatos en el servidor" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Formatos disponibles" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Añadir un nuevo formato para este libro en la base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" "Elimina los formatos seleccionados para este libro de la base de datos." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Buscar portada en el servidor" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "Cambiar nombre de usuario y/o clave de tu cuenta de LibraryThing.com" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Cambiar contraseña" @@ -2056,13 +2813,15 @@ msgid "Tag" msgstr "Etiqueta" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Series" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Formato" @@ -2397,11 +3156,11 @@ msgstr "Nombre de grupo de expresión regular (?P<title>)" #: /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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "Ninguna coincidencia" @@ -2434,103 +3193,102 @@ msgstr "Nombre de grupo de expresión regular (?P<series_index>)" msgid "ISBN:" msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Trabajo" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Estado" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Progreso" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "Tiempo transcurrido en ejecución" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "Terminado" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Error" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" msgstr "En espera..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "Procesando..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "No se puede detener este trabajo" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -"No se pueden detener los trabajos que estan en comunicación con el " -"dispositivo ya que pueden causar corrupción de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "No se pueden detener trabajos ya finalizados" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Ninguno" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Etiquetas" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formatos" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Libro <font face=\"serif\">%s</font> de %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" -msgstr "Doble click para <b>editarme</b>" +msgstr "Doble click para <b>editarme</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Tamaño (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Fecha" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Valoración" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Ruta" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Marca de tiempo" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" "Búsqueda (Para Busqueda Avanzada, haga click en el boton de la izquierda)" @@ -2551,15 +3309,15 @@ msgstr "Partición de palabras" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "<b>Los cambios tendrán efecto una vez reinicie el sistema.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" msgstr " - Visor de LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "<b>No </b>se han encontrado coincidencias para \"<i>%s</i>\"." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "No se han encontrado coincidencias" @@ -2603,11 +3361,11 @@ msgstr "Abrir eBook" msgid "Configure" msgstr "Configurar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Error en la comunicación con el dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" @@ -2615,42 +3373,42 @@ msgstr "" "<p>Para mas ayuda, visite <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "Enviar a la memoria interna" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "Enviar a la tarjeta de memoria" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "y borrar de la biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "enviar a la tarjeta de almacenamiento por defecto" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Editar metadatos individualmente" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Edita metadatos en bloque" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "añadir libros desde un único directorio" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2658,7 +3416,7 @@ msgstr "" "Añadir libros de manera recursiva (un libro por directorio, asumiendo que " "cada archivo del directorio es el mismo libro en diferente formato)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2666,61 +3424,75 @@ msgstr "" "Añadir libros de manera recursiva (Multiples libros por directorio, " "asumiendo que cada archivo es un libro diferente)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Guardar en el disco" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "Guardar en el disco, en un único directorio" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "Guardar solamente el formato %s en disco" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Mostrar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "Ver formato específico" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Convertir individualmente" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Convertir en bloque" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr " detectado." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "Dispositivo: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " detectado." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "Conectado " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "Base de datos del dispositivo corrupta" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2750,8 +3522,8 @@ msgstr "" " </ol>\n" " " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2759,59 +3531,59 @@ msgstr "" "<p>Ya existen libros con el mismo título en la base de datos. ¿Añadirlo de " "todas formas?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "¡Duplicados encontrados!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "Enviando libros al dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "No hay espacio en el dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>No se pueden guardar los libros porque no hay espacio en el dispositivo " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "Eliminando libros del dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "No se pueden editar los metadatos" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "No hay libros seleccionados" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "Enviando libros al dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "No hay formatos adecuados" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" @@ -2819,11 +3591,11 @@ msgstr "" "No se pudieron enviar los siguientes libros al dispositivo, ya que no se " "hallaron formatos adecuados: <br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "No se puede guardar en disco" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" @@ -2831,93 +3603,60 @@ msgstr "" "<p>No se pudieron guardar los siguientes libros en disco, porque el formato " "%s no está disponible para ellos:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "No se pudieron guardar algunos ebooks" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "Busca noticias de " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "Buscando noticias de " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "Noticias adquiridas. Enviando al dispositivo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "No se puede convertir" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "Comenzando conversión en lote de %d libros" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Seleccione un libro" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "No se puede visualizar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "Elija el formato para visualizar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "%s no tiene formatos disponibles" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "No se puede configurar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "No se puede configurar con trabajos en proceso." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "Copiando base de datos a " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "Base de datos no valida" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2925,24 +3664,24 @@ msgstr "" "<p>Ya existe una base de datos no valida en %s, bórrela antes de intentar " "mover la base de datos existente. <br>Error: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "No se puede mover la base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "No hay información detallada disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" "No hay información detallada disponible para los libros en el dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Error de comunicación con el dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2950,15 +3689,16 @@ msgstr "" "Hubo un error de comunicación con el dispositivo. Desconecte, vuelva a " "conectar el dispositivo y reinicie la aplicación." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "Error de conversión" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "No existe la base de datos" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." @@ -2966,7 +3706,11 @@ msgstr "" "El directorio en el que se debería encontrar la base de datos, %s ya no " "existe. Por favor seleccióne una nueva ruta para la base de datos." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" @@ -2974,7 +3718,7 @@ msgstr "" "<span style=\"color:red; font-weight:bold\">Última versión: <a " "href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " @@ -2984,27 +3728,27 @@ msgstr "" "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">nuevas " "características</a>. Visita la página de descarga?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "Actualización disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "Búsqueda avanzada" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Buscar:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -3012,7 +3756,7 @@ msgstr "" "Busca libros por título o autor. <br><br>Los espacios entre palabras se " "sustituyen por AND." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -3020,60 +3764,68 @@ msgstr "" "Buscar libros por título, autor, editorial, etiquetas y " "comentaris<br><br>Los espacios entre parlabras se sustituyen por AND." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Reinicializar búsqueda rápida" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Añadir libros" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Suprimir libros" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Borrar" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Editar la meta-información" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "Enviar al dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Descargar noticias (RSS)" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "F" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "Convertir Ebooks" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "C" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "V" @@ -3086,7 +3838,7 @@ msgstr "" "and stderr). Útil en windows, donde las aplicacines en GUI no tienen cadenas " "de salida." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "ERROR: Excepción no Contemplada" @@ -3107,23 +3859,23 @@ msgstr "" msgid "Custom news sources" msgstr "Nueva fuente de noticias personalizada" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Trabajos:" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "Haga click para ver los trabajos activos." -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "Haga click para explorar los libros por sus cubiertas" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "Haga click para desactivar la exploración de cubiertas" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" @@ -3131,19 +3883,69 @@ msgstr "" "<p>La exploración de los libros por sus cubiertas está desactivada. <br>La " "importación del módulo de pictureflow ha fallado:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Comenzando conversión en lote de %d libros" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Busca noticias de " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" msgstr "Expresión regular no válida" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" msgstr "Expresión regular no valida: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3151,7 +3953,7 @@ msgstr "" "Sony Reader\n" "%s disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3159,39 +3961,38 @@ msgstr "" "Tarjeta\n" "%s disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "Haga click para ver la lista de libros disponibles en su ordenador" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "Haga click para ver la lista de libros disponibles en su lector" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" "Haga click para ver la lista de libros en la tarjeta de almacenamiento de su " "lector" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" -"Camino a la base de datos calibre. El valor predeterminado es a usar la ruta " -"almacenada en la configuración." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -"%prog list [options]\n" -"\n" -"Mostrar los libros disponibles en la base de datos calibre. \n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3203,7 +4004,7 @@ msgstr "" "Campos disponibles: %s\n" "Defecto: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" @@ -3213,11 +4014,11 @@ msgstr "" "Campos disponibles: %s\n" "Defecto: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "Clasificar los resultados en orden ascendente" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 " @@ -3227,15 +4028,15 @@ msgstr "" "consulta de búsqueda consulte la documentación relacionada con la búsqueda " "en el Manual del usuario. El valor predeterminado es a no hacer el filtrado." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "Campos no válidos. Los campos disponibles:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "Campo de clasificación no válido. Los campos disponibles:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" @@ -3243,22 +4044,16 @@ msgstr "" "Los siguientes libros no se han añadido como ya existen en la base de datos " "(véase la opción --duplicates)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -"%prog add [options] file1 file2 file3 ...\n" -"\n" -"Añadir los archivos especificados como libros a la base de datos. También " -"puede especificar\n" -"directorios, consulte las opciones relacionadas a los directorios más abajo. " -"\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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" @@ -3266,11 +4061,11 @@ msgstr "" "Supongamos que cada directorio tiene un solo libro lógico y que todos los " "archivos en este directorio son diferentes formatos de este libro" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "Proceso de directorios recursivamente" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." @@ -3278,11 +4073,11 @@ msgstr "" "Añadir a base de datos de libros, aunque ya existen. La comparación se " "realiza sobre la base de títulos de libros." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "Debe especificar al menos un archivo para añadir" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3297,11 +4092,11 @@ msgstr "" "números de identificación utilizando el commando \"list\"). Por ejemplo, " "23,34,57-85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "Debe especificar al menos un libro para eliminar" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3315,15 +4110,15 @@ msgstr "" "identificado por iid. Puede obtener el id usando el comando list. Si el " "formato ya existe, será reemplazado por el nuevo.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "Debe especificar un ID y un ebook archivo" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "ebook archivo debe tener una extensión" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3340,34 +4135,29 @@ msgstr "" "archivo como LRF o TXT o EPUB. Si el libro lógico no tiene fmt disponible, " "no hacer nada.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "Debe especificar un ID y un formato" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -"\n" -"%prog show_metadata [options] id\n" -"Muestra los metadatos almacenados en la Base de Datos de calibre para el " -"libro identificado por ID.\n" -"Id es un número de identificador de la lista de comandos. \n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "Imprimir metadatos en formato OPF (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "Usted debe especificar un ID" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3375,91 +4165,119 @@ msgid "" "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" +"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 "" -"\n" -"%prog set_metadata [opciones] id /ruta/de/metadata.opf\n" -"\n" -"Establece los metadatos almacenados en la base de datos de calibre para el " -"libro\n" -"identificado por el número id, a partir de archivo OPF de metadatos " -"\"metadata.opf\".\n" -"Puede obtener información del formato OPF usando el modificador --as-opf en " -"el \n" -"comando show_metadata.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "Usted debe especificar un ID y un archivo de metadatos" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" -"%prog export [opciones] ids \n" -"\n" -"Exporta los libros indicado por ids (una lista separada por comas) al " -"sistema de archivos. \n" -"Esta operación de exportación guardará todos los formatos del libro, la " -"portada y los metadatos \n" -"(en un archivo opf). Puede obtener los numeros id a partir del comando list. " -"\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" "Exportar todos los libros en la base de datos, haciendo caso omiso de la " "lista de identificaciones." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" "Exportar libros para el directorio especificado. El valor por defecto es" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "Exportar todos los libros en un solo directorio" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" "Crear nombres de archivo como autor - título en lugar de título - autor" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "Debe especificar algunas identificaciones o la opción %s" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -"%%prog command [opciones] [argumentos]\n" -"\n" -"%%prog es la interfaz en linea de comandos a la base de datos de libros de " -"calibre\n" -"\n" -"command es uno de:\n" -"%s\n" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "No se ha podido abrir el proceso trabajador." +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sUso%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Creado por " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "No se ha podido inicializar la biblioteca fontconfig" @@ -3490,7 +4308,152 @@ msgstr "Newsfeed desconocido" msgid "Untitled article" msgstr "Artículo sin título" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Tiempo máximo de espera de respuesta por parte del servidor (en segundos). " +"Por omisión es %default segundo(s)" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Intervalo minimo de segundos entre adquisiciones de datos consecutivas. Por " +"omisión %s segundos" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"Codificación de caracteres para los sitios web que está intentando " +"descargar. Por omisión se intentará averiguar la codificación." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Sólo se seguirán los enlaces que cumplan la expresión regular. Esta opción " +"se puede usar varias veces, en cuyo caso siempre que el elace cumpla alguna " +"de las expresiones regulares, el enlace será seguido. Por omisión todos los " +"enlaces se siguen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Cualquier enlace que cumpla la expresión regular será ignorado. Esta opción " +"se puede usar varias veces, en cuyo caso, siempre que el enlace cumpla " +"alguna de las expresiones regulares, el enlace será ignorado. Por omisión, " +"ningún enlace se ignora. Si ambas opciones --filter-regexp y --match-regexp " +"so usadas, entonces --filter-regexp se aplica primero." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "No descargar hojas de estilo CSS" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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 "" +"Especificar una lista de feeds para descargar. Por ejemplo:\n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"Si especifica esta opción, cualquier argumento de %prog será ignorado y se " +"usará una receta por omisión para descargar los feeds." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "Ofrecer amplia información mientras se está procesando" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"El título para esta receta. Usado como título por alguno de los libros " +"creados por los feeds descargados." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" +"Nombre de usuario para los sitios que requieren login para acceder a su " +"contenido" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" +"Contraseña para sitios que requieren login para acceder al contenido." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Número de niveles de enlaces a profundizar en páginas web que son enlazadas " +"desde feeds. Por defecto %default" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"El directorio en el cual se almacenan los feeds descargados. Por omisión se " +"utilizará el directorio actual." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "Salida extremadamente detallada, útil para depuración." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Útil para desarrollo de recetas. Fuerza max_articles_per_feed a 2 y descarga " +"2 feeds como máximo." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3531,147 +4494,82 @@ msgstr "" "Recetas propias disponibles son:\n" "%s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" "Opciones para controlar web2disk (usado para obtener sitios web enlazados " "mediente feeds)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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 "" -"Especificar una lista de feeds para descargar. Por ejemplo:\n" -"\"['http://feeds.newsweek.com/newsweek/TopNews', " -"'http://feeds.newsweek.com/headlines/politics']\"\n" -"Si especifica esta opción, cualquier argumento de %prog será ignorado y se " -"usará una receta por omisión para descargar los feeds." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 -msgid "Be more verbose while processing." -msgstr "Ofrecer amplia información mientras se está procesando" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -msgid "" -"The title for this recipe. Used as the title for any ebooks created from the " -"downloaded feeds." -msgstr "" -"El título para esta receta. Usado como título por alguno de los libros " -"creados por los feeds descargados." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:47 -msgid "Username for sites that require a login to access content." -msgstr "" -"Nombre de usuario para los sitios que requieren login para acceder a su " -"contenido" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" -"Contraseña para sitios que requieren login para acceder al contenido." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" -"Número de niveles de enlaces a profundizar en páginas web que son enlazadas " -"desde feeds. Por defecto %default" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "" -"The directory in which to store the downloaded feeds. Defaults to the " -"current directory." -msgstr "" -"El directorio en el cual se almacenan los feeds descargados. Por omisión se " -"utilizará el directorio actual." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "No mostrar la barra de progreso" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "Salida extremadamente detallada, útil para depuración." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -msgid "" -"Useful for recipe development. Forces max_articles_per_feed to 2 and " -"downloads at most 2 feeds." -msgstr "" -"Útil para desarrollo de recetas. Fuerza max_articles_per_feed a 2 y descarga " -"2 feeds como máximo." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "Buscando newsfeeds..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "Fuente de noticias desconocida" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "Descarga finalizada" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "Error al descargar los siguientes artículos:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr " de " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "Error al descargar partes de los siguientes artículos" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "\tEnlaces erroneos:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" "No se pudo obtener el artículo. Ejecute con la opción --debug para encontrar " "la causa del fallo" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "Feeds obtenidos de página índice" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "Intentando descargar la portada" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "Iniciando la descarga [%d hilo(s)]" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "Feeds descargados a %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "No fué posible descargar la portada: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "Descargando portada desde %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "Artículo sin título" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" @@ -3681,23 +4579,23 @@ msgstr "" "Artículo %s descargado desde %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "Artículo descargado: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "No se ha podido descargar el artículo: %s de %s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "Error en la descarga del artículo: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "Buscando newsfeed" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" @@ -3707,19 +4605,11 @@ msgstr "" "\n" "Donde URL es por ejemplo http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "Directorio base en el cual se almacena URL. Por omisión es %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Tiempo máximo de espera de respuesta por parte del servidor (en segundos). " -"Por omisión es %default segundo(s)" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3727,7 +4617,7 @@ msgstr "" "Máximo número de niveles de recursión, es decir, profundidad de los enlaces " "a seguir. Por omisión %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3735,51 +4625,6 @@ msgstr "" "El número máximo de archivos a descargar. Esto se aplica solamente a " "archivos procedentes de una etiqueta <a href>. Por omisión es %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Intervalo minimo de segundos entre adquisiciones de datos consecutivas. Por " -"omisión %s segundos" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -msgid "" -"The character encoding for the websites you are trying to download. The " -"default is to try and guess the encoding." -msgstr "" -"Codificación de caracteres para los sitios web que está intentando " -"descargar. Por omisión se intentará averiguar la codificación." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:400 -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 "" -"Sólo se seguirán los enlaces que cumplan la expresión regular. Esta opción " -"se puede usar varias veces, en cuyo caso siempre que el elace cumpla alguna " -"de las expresiones regulares, el enlace será seguido. Por omisión todos los " -"enlaces se siguen." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 -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 "" -"Cualquier enlace que cumpla la expresión regular será ignorado. Esta opción " -"se puede usar varias veces, en cuyo caso, siempre que el enlace cumpla " -"alguna de las expresiones regulares, el enlace será ignorado. Por omisión, " -"ningún enlace se ignora. Si ambas opciones --filter-regexp y --match-regexp " -"so usadas, entonces --filter-regexp se aplica primero." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "No descargar hojas de estilo CSS" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "Mostrar información de salida detallada. Útil para depuración" diff --git a/src/calibre/translations/fr.po b/src/calibre/translations/fr.po index 3b47ccc75f..5514e49473 100644 --- a/src/calibre/translations/fr.po +++ b/src/calibre/translations/fr.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.22\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-08-01 22:21+0000\n" -"Last-Translator: JVC <Unknown>\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-08-28 13:18+0000\n" +"Last-Translator: Anthony Guéchoum <Unknown>\n" "Language-Team: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" @@ -65,6 +65,9 @@ msgstr "" #~ msgid "Server error. Try again later." #~ msgstr "Erreur Serveur. Veuillez essayer ultérieurement." +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "&Emplacement de la base de données (library1.db)" + #~ msgid "&Access Key;" #~ msgstr "&Access Key;" @@ -181,51 +184,351 @@ msgstr "" #~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-" #~ "family:'Sans Serif';\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sUsage%s: %s\n" +#~ 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" +#~ msgstr "" +#~ "<!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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Créé par " - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." -msgstr "Impossible de détecter le lecteur %s. Réessayer après redémarrage." +msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "Le lecteur n'a pas de carte de stockage connectée." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Inconnu" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." -msgstr "Dossier de récupération. Par défaut, il s'agit du dossier actuel." +msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Utile pour déboguer" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" -msgstr "OEB ebook créé dans" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 -#, fuzzy -msgid "Set the title. Default: filename." -msgstr "Indiquer le titre. Par défaut: filename." +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +msgid "Set the title. Default: filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -233,49 +536,34 @@ msgstr "" "Définir le(s) auteur(s). Si plusieurs auteurs, les séparer d'une virgule. " "Par défaut : %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Inconnu" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Définir le commentaire" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Définir la catégorie" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Clé de tri pour le titre" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Clé de tri pour l'auteur" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Éditeur" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Chemin du fichier contenant l'image à utiliser comme couverture" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -283,12 +571,11 @@ msgstr "" "Si une couverture est déctectée dans le fichier source, utilise cette image " "plutôt que l'image spécifiée." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 -#, fuzzy -msgid "Output file name. Default is derived from input filename" -msgstr "Nom du fichier sortie. Basé par défaut sur le fichier d'entrée" - #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +msgid "Output file name. Default is derived from input filename" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -297,36 +584,31 @@ msgstr "" "véritables tables. Cela peut être nécessaire si le HTML contient des tables " "trop grosses ou complexes ." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 "" -"Spécifier la taille de la police originelle en pts. Toutes les polices sont " -"redimensionnées en conséquence. Cette option enlève l'option --font-delta et " -"lui est prioritaire. Pour utiliser --font-delta, régler-le à 0. Par défault: " -"%defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Activer l'autorotation des images plus larges que la largeur de l'écran." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "Définit les epsaces entre les mots en pts. Par défaut : %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Séparer les paragraphes par des lignes vides." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Rajoute une en-tête à toutes les pages, avec le titre et l'auteur." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -334,7 +616,7 @@ msgstr "" "Définit le format de l'en-tête de page. %a est remplacé par l'auteur et %t " "par le titre. Par défaut : %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -343,7 +625,7 @@ msgstr "" "style CSS ou une chaîne de caractères. Si c'est une chaîne, elle est " "interprétée comme du CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -353,7 +635,7 @@ msgstr "" "les fichiers HTML sont ajoutés au LRF. Le fichier .opf doit être dans le " "même répertoire que le fichier HTML de base." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -361,7 +643,7 @@ msgstr "" "Indentation minimum du paragraphe (l'indentation de la première ligne d'un " "paragraphe) en pts. Par défault: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -371,7 +653,7 @@ msgstr "" "FONT_DELTA points. FONT_DELTA peut-être un nombre décimal. Si FONT_DELTA est " "négatif, la taille de la police est réduite." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." @@ -379,7 +661,7 @@ msgstr "" "Rendre noir et blanc tous les contenus au lieu des couleurs spécifiées par " "le HTML ou CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -389,23 +671,23 @@ msgstr "" "paramètres comme la résolution et la taille de l'écran du lecteur. Par " "défaut : %s Profils supportés : " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "La marge de gauche. Par défaut : %default px" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "La marge de droite. Par défaut : %default px." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "La marge de haut de page. Par défaut : %default points." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "La marge de bas de page. Par défaut : %default points." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -413,7 +695,7 @@ msgstr "" "Convertir les tables dans le HTML en images (utile si le document a des " "tables grandes ou complexes)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -421,7 +703,7 @@ msgstr "" "Multiplier la taille du texte des tables selectionnées par ce facteur. " "Facteur par défault: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -431,7 +713,7 @@ msgstr "" "indique qu'aucun lien ne sera traité. Une valeur négative indique que les " "tags <a> sont ignorés." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -439,15 +721,15 @@ msgstr "" "Une expression habituelle. Les étiquettes <a> ayant leur href qui correspond " "seront ignorées. Par défault: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Ne pas ajouter de liens à la table des matières." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Empêcher la détection automatique des chapitres." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -456,15 +738,17 @@ msgstr "" "expression rest recherchée dans les tags d'en-têtes (h1-h6). Par défaut : " "%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -483,12 +767,12 @@ msgstr "" "page. De ce fait, cette option est ignorée si la page courante a peu " "d'éléments." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -501,16 +785,16 @@ msgstr "" "de classe \"chapter\" il faudrait saisir : \"h\\d,class,chapter\". Par " "défaut : %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Ajouter les chapitres détectés à la table des matières." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" "Préprocesse les fichiers HTML Bean pour améliorer le fichier LRF généré." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -518,12 +802,12 @@ msgstr "" "Vous devez utiliser cette option pour traiter des fichiers générés par " "pdftohtml, sinon la conversion échouera." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "" "Utilisez cette option sur des fichiers html0 venant de Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -531,27 +815,27 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "La famille de police serif à inclure" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "La famille de police sans-serif à inclure" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "La famille de police monospace à inclure" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Montrer les détails lors des traitements" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Convertir en LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -560,7 +844,7 @@ msgstr "" "long. N'utilisez cette option que si vous avez des problèmes de mémoire " "disponible." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -573,7 +857,7 @@ msgstr "" "Windows est le cp-1252. Cela peut aussi être l'utf-8. Le mieux est d'essayer " "et deviner quel est l'encodage approprié." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -590,100 +874,118 @@ msgstr "" "RAR ou ZIP, en recherchant les ebooks à l'intérieur de l'archive.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Aucun fichier sélectionné à convertir." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" "Titre pour le livre électronique créé. Par défaut le nom de fichier sera " "utilisé." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" -"Mettez le nom de l'auteur dans les données meta de l'ebook généré. Par " -"défaut, ce sera %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -"Chemin vers le fichier LRF récupéré. par défaut, un fichier est créé dans le " -"répertoire actuel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" +"Nombre de teintes pour la conversion de l'image en échelle de gris. Défaut: " +"%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -696,7 +998,7 @@ msgstr "" " \n" "%prog convertit mybook.epub en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -708,41 +1010,38 @@ msgstr "" "\n" "%prog convertit mybook.fb2 en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Imprimer l'HTML généré en stdout et quitter" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "Conserver les fichiers HTML générés après conversion en LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Options pour contrôler le comportement de feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Options pour contrôler le comportement de html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " -msgstr "Recherche des recettes échouées: " +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316 -#, fuzzy msgid "\tBook Designer file detected." -msgstr "\tFichier Créateur de Livre détecté" +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 msgid "\tParsing HTML..." msgstr "\tAnalyse de l'HTML..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 -#, fuzzy msgid "\tBaen file detected. Re-parsing..." -msgstr "\tFichier Baen détecté. Ré-analyse..." +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 msgid "Written preprocessed HTML to " @@ -756,33 +1055,32 @@ msgstr "Traitement de %s" msgid "\tConverting to BBeB..." msgstr "\tConversion en BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Ne peut analyser le fichier: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%s est un fichier vide" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "Érreur d'analyse du lien %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "Ne peut ajouter le lien %s au TOC" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Incapable de traiter l'image %s. Erreur: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" -msgstr "Incapable de traiter les PNG entrelacés %s" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -790,15 +1088,12 @@ msgstr "" "Ne peut traiter l'image: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" -"Une erreur a surgit lors d'un traitement de table: %s. Ignore la table " -"majorée" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -806,11 +1101,11 @@ msgstr "" "Mauvaise table:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "La table a une cellule trop grande" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -818,19 +1113,19 @@ msgstr "" "Vous devez tout d'abord sauvegarder le site web %s en fichier html, puis le " "lancer avec html2lrf." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "Ne peut lire l'image de couverture: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "Ne peut lire depuis: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Tentative de traitement du fichier opf échouée" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -848,7 +1143,7 @@ msgstr "" "les fichiers locaux. Ainsi, vous pouvez l'utiliser pour \n" "convertir toute une arborescence de fichiers HTML." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -860,7 +1155,7 @@ msgstr "" "\n" "%prog convertit mybook.lit ten mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -868,27 +1163,27 @@ msgstr "" "%prog book.lrf\n" "Convertit un fichier LRF en un fichier LRS (encodage XML UTF-8)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Fichier sortie LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Analyse du LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Création du XML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS écrit à " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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." @@ -896,27 +1191,24 @@ msgstr "" "%prog [options] file.lrs\n" "Compile un fichier LRS en un fichier LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Chemin vers le fichier sortie" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" -msgstr "Traitement en cours" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "Convertir LRS en LRS, utile pour déboguer." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:455 -#, fuzzy msgid "Invalid LRF file. Could not set metadata." -msgstr "Fichier LRF invalide. Ne peut régler la métadonnée." +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:580 -#, fuzzy msgid "" "%prog [options] mybook.lrf\n" "\n" @@ -924,14 +1216,9 @@ msgid "" "Show/edit the metadata in an LRF file.\n" "\n" msgstr "" -"%prog [options] mybook.lrf\n" -"\n" -"\n" -"Montrer/Éditer la métadonnée en un fichier LRF.\n" -"\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Définit le titre du livre" @@ -948,7 +1235,7 @@ msgid "Set sort key for the author" msgstr "Définit la clef de tri pour l'auteur" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "La catégorie à laquelle le livre appartient. Exemple : Histoire" @@ -997,22 +1284,22 @@ msgstr "" "\n" "%prog convertit mybook.mobi en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " ne permet pas de copier du texte." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" " est une image codée en PDF. Seule la conversion des textes est suportée " "pour les PDFs." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -1024,21 +1311,21 @@ msgstr "" "\n" "%prog convertit mybook.pdf en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Détaillez plus." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "Vous devez sélectionner un seul fichier PDF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -1050,7 +1337,13 @@ msgstr "" "\n" "%prog convertit mybook.rtf en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -1062,23 +1355,33 @@ msgstr "" "\n" "%prog convertit mybook.txt en mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Configurer les auteurs." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Configurer les commentaires." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Usage:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Pas de nom de fichier spécifié." + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -1103,23 +1406,23 @@ msgstr "" "sur isbndb.com.\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "L'ISBN ID du livre dont vous désirez les métadonnées." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "L'auteur du livre à chercher." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "le titre du livre à chercher." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "L'éditeur du livre à chercher." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1127,16 +1430,16 @@ msgstr "" "L'image de couverture n'a pas pu être récupérée à cause de problèmes de " "connexion. Veuillez réessayer ultérieurement." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " pas trouvé." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "Erreur du serveur LibraryThing.com. Veuillez réessayer plus tard." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1161,96 +1464,221 @@ msgstr "Couverture sauvée sur" msgid "Usage: pdf-meta file.pdf" msgstr "Usage: pdf-meta file.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Pas de nom de fichier spécifié." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [options] myebook.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Répertoires utilisés fréquemment" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Titre" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Commentaires" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Chemin" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formats" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Boîte de dialogue" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TextLabel" +#: /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 "Choisir le format" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Profil :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -1261,53 +1689,57 @@ msgstr "Mode Basique" msgid "Advanced" msgstr "Mode avancé" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "<br>Doit être un répertoire." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Chemin de la database invalide " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Chemin de la database invalide" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Doit être un répertoire." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Chemin de la database invalide " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "Chemin de la database invalide.<br>Erreur en écriture " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Configuration" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "&Emplacement de la base de données (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Choisir un nouvel emplacement pour la base de données" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1315,100 +1747,117 @@ msgstr "Choisir un nouvel emplacement pour la base de données" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "Utilisation de chiffres romains pour les numéro de séries" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "Envoyer une notification quand une nouvelle version est disponible." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "&Priorité pour les travaux de conversion :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "&Timeout par défaut pour les connexions réseau :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " secondes" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Barre d'outils" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Large" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Moyen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Petit" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Répertoires utilisés fréquemment" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "Ajouter un répetoire à la liste des répertoires utilisés fréquemment" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" "Supprime un répetoire de la liste des répertoires utilisés fréquemment" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Espace libre non-utilisé de la base de données" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1416,10 +1865,341 @@ msgstr "" msgid "ERROR" msgstr "ERREUR" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Metadata" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Présentation" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Mise en page" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Détection des chapitres" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "Peaufiner la détection des chapitres et des en-têtes de section." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Impossible de lire" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Vous n'avez pas les permissions nécessaires pour lire ce fichier: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Erreur à la lecture du fichier" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Il y a eu une erreur à la lecture du fichier : <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " n'est pas une image vailde" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Conversion impossible" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Aucun format disponible" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" +"Conversion du livre %s impossible parcequ'il ne dispose d'aucun format " +"supporté" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Couverture du livre" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "Modifie l'image &cover :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Rechercher une image à utiliser en tant que couverture du livre." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Utilise l'image de couverture du fichier &source" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Titre : " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Modifie le titre du livre" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Auteurs : " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Modifie les auteurs du livres. Si plusieurs auteurs, les séparer avec des " +"virgules." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "T&ri de l'auteur :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Editeur : " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Modifie l'éditeur du livre" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "Ta&gs : " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" +"Tags caractérisant le livre, particulièrement utile pour la recherche. <br> " +"<br> Cela peut être n'importe quels mots, séparés par des virgules." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Séries :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Liste de séries connues. Vous pouvez ajouter de nouvelles séries." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Index de séries" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Livre " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "Marge &Gauche :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "Marge &Droite :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "Marge &Haute :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "Marge &Basse :" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Auteur(s)" @@ -1510,36 +2290,6 @@ msgstr "Exécutions en cours" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Metadata" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Présentation" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Mise en page" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Détection des chapitres" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Aucun format disponible" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" -"Conversion du livre %s impossible parcequ'il ne dispose d'aucun format " -"supporté" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Choix du format de conversion vers LRF" @@ -1549,33 +2299,10 @@ msgid "Convert %s to LRF" msgstr "Conversion de %s en LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Définir les paramètres par défaut de conversion" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "Impossible de lire" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "Vous n'avez pas les permissions nécessaires pour lire ce fichier: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Erreur à la lecture du fichier" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "<p>Il y a eu une erreur à la lecture du fichier : <br /><b>" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " n'est pas une image vailde" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1624,10 +2351,6 @@ msgstr "" "Définit les paramètres de la pages tels que les marges et la taille de " "l'écran du lecteur cible." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "Peaufiner la détection des chapitres et des en-têtes de section." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">Aucune aide n'est disponible</font>" @@ -1636,311 +2359,177 @@ msgstr "<font color=\"gray\">Aucune aide n'est disponible</font>" msgid "Bulk convert ebooks to LRF" msgstr "Bulk convertit les ebooks en LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Convertir en LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Catégorie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Options" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Couverture du livre" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "Modifie l'image &cover :" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Rechercher une image à utiliser en tant que couverture du livre." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Utilise l'image de couverture du fichier &source" - -#: /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:263 -msgid "&Title: " -msgstr "&Titre : " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Modifie le titre du livre" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Auteurs : " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Modifie les auteurs du livres. Si plusieurs auteurs, les séparer avec des " -"virgules." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "T&ri de l'auteur :" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Editeur : " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Modifie l'éditeur du livre" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "Ta&gs : " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"<br><br>They can be any words or phrases, separated by commas." -msgstr "" -"Tags caractérisant le livre, particulièrement utile pour la recherche. <br> " -"<br> Cela peut être n'importe quels mots, séparés par des virgules." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Séries :" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Liste de séries connues. Vous pouvez ajouter de nouvelles séries." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Index de séries" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Livre " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Taille de &police par défaut :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " pts" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Polices inclues" -#: /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:531 msgid "&Serif:" msgstr "&Serif :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif :" -#: /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:533 msgid "&Monospace:" msgstr "&Monospace :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" msgstr "Espacement entre &mots :" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Active l'auto &rotation des images" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "Insère des lignes &blanches entre les paragraphes" -#: /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:541 msgid "Ignore &tables" msgstr "Ignore les &tables" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" msgstr "&Preprocess :" -#: /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:544 msgid "Header" msgstr "En-têtre" -#: /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:545 msgid "&Show header" msgstr "&Affiche l'en-tête" -#: /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:546 msgid "&Header format:" msgstr "Format de l'&en-tête" -#: /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:547 msgid "Override<br>CSS" msgstr "Surcharge <br> CSS" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "Marge &Gauche :" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " px" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "Marge &Droite :" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "Marge &Haute :" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "Marge &Basse :" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Détection basée sur les titres" -#: /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:560 msgid "&Disable chapter detection" msgstr "&Désactive la détection de chapitres" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "Expression &Régulière :" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" msgstr "Détection basée sur des tags" -#: /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:565 msgid "&Page break before tag:" msgstr "Saut de &page avant le tag:" -#: /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:566 msgid "&Force page break before tag:" msgstr "&Force un saut de page avant le tag:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Force un saut de page avant l'&attribut :" -#: /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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" msgstr "Aide" -#: /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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" msgstr "" -"<!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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:114 msgid "Edit Meta information" msgstr "Editer les informations Metadata" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Informations (metadata)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "Clé de tr&i de l'auteur : " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1949,19 +2538,19 @@ msgstr "" "Dickens peut être classé comme Dickens, Charles." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Note :" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Note de ce livre. de 0 à 5 étoiles" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " étoiles" @@ -1971,8 +2560,8 @@ msgstr "Ajout de Ta&gs : " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Ouvre l'éditeur de mots-clefs" @@ -1984,7 +2573,7 @@ msgstr "&Supprime des mots-clefs :" msgid "Comma separated list of tags to remove from the books. " msgstr "Liste de mots-clefs séparés par des virgules à retirer des livres. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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> " @@ -1994,67 +2583,72 @@ msgstr "" "<b>LibraryThing.com</b>. <br/>Si vous n'en avez pas, vous pouvez <a " "href='http://www.librarything.com'>y créer un compte </a> gratuitement !</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "<b>Erreur à la récupération de l'image de couverture.</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "Erreur à la récupération de l'image de couverture" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "Erreur à la récupération de l'image de couverture" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Vous devez fournir l'identifiant ISBN de ce livre." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Edition des metadata" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" "Supprimer les séries inutilisées (Les séries qui ne possèdent aucun livres)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "I&SBN :" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Récupération des metadata depuis le serveur" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Formats disponibles" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Ajout d'un nouveau format dans la base de données pour ce livre" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "Retire les formats sélectionnés de ce livre de la base de données." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Récupération de l'image de couverture depuis le serveur" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" "Modifie le nom d'utilisateur et/ou le mot de passe de votre compte à " "LibraryThing.com" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Modifie le mot de passe" @@ -2083,13 +2677,15 @@ msgid "Tag" msgstr "Étiquette" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Séries" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Format" @@ -2399,11 +2995,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2436,101 +3032,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Travaux" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Statut" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Progression" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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 "En attente" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "En cours" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Aucun" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Tags" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formats" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Livre <font face=\"serif\">%s</font> of %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Taille (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Date" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Note" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Chemin" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Horodatage" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2550,15 +3147,15 @@ msgstr "Hyphenation" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /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 "<b>Aucun résultat</b> pour la recherche <i>%s</i>." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "Aucun résultat" @@ -2602,52 +3199,52 @@ msgstr "Ouvrir le livre" msgid "Configure" msgstr "Configuration" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Erreur pendant la communication avec le lecteur électronique" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 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:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 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:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "Envoi vers la mémoire du lecteur" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "Envoi vers la carte mémoire" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Edition des metadata individuellement" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Edition des metadata par lot" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2655,7 +3252,7 @@ msgstr "" "Ajouter des livres récursivement (un livre par répertoire, assume que chaque " "fichier correspond au même livre mais dans un format différent)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2663,61 +3260,75 @@ msgstr "" "Ajouter des livre récursivement (Plusieurs livres par répertoire, considère " "que chaque fichier est un livre différent)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Enregistrer sur le disque" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Visualiser" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Convertion individuelle" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Convertion par lot" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2733,8 +3344,8 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2742,162 +3353,129 @@ msgstr "" "<p>Des livres ayant le même titre existent déjà dans la base de données. Les " "ajouter quand même ?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "Des doublons ont été détectés !" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Le lecteur électronique n'a plus d'espace mémoire disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>Impossible d'envoyer les livres sur le lecteur : il n'y a plus assez " "d'espace mémoire disponible " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "Erreur à l'édition des metadat" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Aucun livre sélectionné" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 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:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "Ne peut pas enregistrer sur le disque" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "Impossible de sauvegarder des livres électroniques" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "Conversion impossible" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Aucun livre sélectionné" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "Impossible de visualiser" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "Configuration impossible" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "Impossible de configurer pendant que des travaux sont en cours." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "Base de données invalide" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2905,23 +3483,23 @@ msgstr "" "<p>Une base de données invalide existe déjà ici : %s, spprimez la avant " "d'essayer de déplacer la base de données existante.<br>Erreur : %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "Déplacement de la base de données impossible" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Erreur pendant la communication avec le lecteur électronique" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2930,54 +3508,59 @@ msgstr "" "lecteur électronique. Veuillez déconnecter et reconnecter le lecteur " "électronique et redémarrer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Recherche :" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -2985,7 +3568,7 @@ msgstr "" "Recherche les livres par titre ou auteur <br><br>Recherche en ET pour les " "mots séparés par des espaces." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -2993,60 +3576,68 @@ msgstr "" "Recherche les livres par titre, auteur, éditeur, tags et commentaires " "<br><br>Recherche en ET pour les mots séparés par des espaces." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Réinitialisation de la recherche rapide" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Ajout d'un livre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Suppression du livre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Suppression" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Edition des metadata" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "Envoyer au lecteur" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Récupérer des News" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -3056,7 +3647,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -3074,41 +3665,91 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Travaux :" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Librairie" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3116,7 +3757,7 @@ msgstr "" "Lecteur \n" "%s disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3124,32 +3765,36 @@ msgstr "" "Carte\n" "%s disponible" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3157,68 +3802,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3227,11 +3872,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3240,17 +3885,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -"Vous devez spécifier un identifiant et un fichier de livre électronique" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "Les fichiers de livres électroniques doivent avoir une extension" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3260,29 +3903,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3290,62 +3933,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sUsage%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Créé par " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -3376,7 +4072,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3397,210 +4207,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 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:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/translations/gl.po b/src/calibre/translations/gl.po new file mode 100644 index 0000000000..524860298b --- /dev/null +++ b/src/calibre/translations/gl.po @@ -0,0 +1,3944 @@ +# Galician translation for calibre +# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008 +# This file is distributed under the same license as the calibre package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: calibre\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-30 12:33+0000\n" +"Last-Translator: Calidonia <Unknown>\n" +"Language-Team: Galician <gl@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: 2008-10-06 00:28+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 +msgid "Unable to detect the %s disk drive. Try rebooting." +msgstr "Non se puido detectar a unidade de disco %s. Probe a reiniciar." + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 +msgid "The reader has no storage card connected." +msgstr "O lector non ten conectada tarxeta de almacenamento ningunha" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Opcións para controlar a conversión a EPUB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"Se non se especifica o ficheiro EPUB de saída empregarase o mesmo nome do " +"ficheiro de entrada." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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 "" +"O perfil do dispositivo de destino ao que se refire o EPUB. Escolla Ningún " +"para crear un EPUB independente do dispositivo. O perfil úsase para " +"establcer restricións específicas no EPUB. As opcións son: " + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 +msgid "%prog [options] LITFILE" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +msgid "Output directory. Defaults to current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 +msgid "Useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 +msgid "OEB ebook created in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +msgid "Set the title. Default: filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 +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:78 +msgid "Set the comment." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +msgid "Set the category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +msgid "Sort key for the title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +msgid "Sort key for the author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 +msgid "Publisher" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +msgid "Path to file containing image to be used as cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 +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:93 +msgid "Output file name. Default is derived from input filename" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 +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:98 +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:100 +msgid "Enable autorotation of images that are wider than the screen width." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +msgid "Set the space between words in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +msgid "Separate paragraphs by blank lines." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +msgid "Add a header to all the pages with title and author." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +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:111 +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:113 +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:115 +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:117 +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:122 +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:128 +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:134 +msgid "Left margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +msgid "Right margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +msgid "Top margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +msgid "Bottom margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +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:144 +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:149 +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:153 +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:157 +msgid "Don't add links to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 +msgid "Prevent the automatic detection chapters." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 +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:167 +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:169 +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:179 +msgid "" +"Force a page break before tags whose names match this regular expression." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 +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:184 +msgid "Add detected chapters to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +msgid "Preprocess Baen HTML files to improve generated LRF." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +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:191 +msgid "Use this option on html0 files from Book Designer." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 +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:202 +msgid "The serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 +msgid "The sans-serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 +msgid "The monospace family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +msgid "Be verbose while processing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +msgid "Convert to LRS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +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:218 +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:152 +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:167 +msgid "No file to convert specified." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 +msgid "Rendered %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 +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:284 +msgid "Title for generated ebook. Default is to use the filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 +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:289 +msgid "" +"Path to output LRF file. By default a file is created in the current " +"directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 +msgid "" +"Disable normalize (improve contrast) color range for pictures. Default: False" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 +msgid "Maintain picture aspect ratio. Default is to fill the screen." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 +msgid "Disable sharpening." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 +msgid "Don't split landscape images into two portrait images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 +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:309 +msgid "" +"Choose a profile for the device you are generating this LRF for. The default " +"is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 +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:313 +msgid "Don't show progress bar." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 +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:378 +msgid "Output written to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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:316 +msgid "\tBook Designer file detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 +msgid "\tParsing HTML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 +msgid "\tBaen file detected. Re-parsing..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 +msgid "Written preprocessed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 +msgid "Processing %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 +msgid "\tConverting to BBeB..." +msgstr "" + +#: /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 +msgid "Could not parse file: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:537 +msgid "%s is an empty file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 +msgid "Failed to parse link %s %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 +msgid "Cannot add link %s to TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 +msgid "Unable to process image %s. Error: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 +msgid "Unable to process interlaced PNG %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 +msgid "" +"Could not process image: %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 +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:1760 +msgid "" +"Bad table:\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 +msgid "Table has cell that is too large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 +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:1855 +msgid "Could not read cover image: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 +msgid "Cannot read from: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +msgid "Failed to process opf file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 +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:133 +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:134 +msgid "Output LRS file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 +msgid "Parsing LRF..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 +msgid "Creating XML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 +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:114 +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:22 +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:26 +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:607 +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:609 +msgid "Set book ID" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 +msgid "Don't know what this is for" +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:56 +msgid " does not allow copying of text." +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:24 +msgid "Set the authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 +msgid "Set the comment" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 +msgid "A comma separated list of tags to set" +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:37 +#: /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:96 +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:107 +msgid "The ISBN ID of the book you want metadata for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 +msgid "The author whose book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 +msgid "The title of the book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +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:40 +msgid "Usage: %s file.lit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:50 +msgid "Cover saved to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:36 +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/reader.py:421 +msgid "%prog [options] myebook.mobi" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 +msgid "Raw MOBI HTML saved in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 +msgid "Title" +msgstr "" + +#: /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:356 +#: /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:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 +msgid "Comments" +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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/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/password_ui.py:56 +#: /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:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +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:23 +msgid "Basic" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:24 +msgid "Advanced" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 +msgid "Invalid database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 +msgid "Invalid database location.<br>Cannot write to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting database. This may take a while." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +msgid "Configuration" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:236 +msgid "Browse for the new database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 +#: /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:226 +#: /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:229 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +msgid "..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +msgid "Use &Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 +msgid "&Number of covers to show in browse mode (after restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +msgid "Show notification when &new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 +msgid "Ask for &confirmation before deleting files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +msgid "Format for &single file save:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 +msgid "&Priority for conversion jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +msgid "Default network &timeout:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +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:246 +msgid " seconds" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 +msgid "Toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 +msgid "Large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 +msgid "Medium" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 +msgid "Small" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 +msgid "&Button size in toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 +msgid "Show &text in toolbar buttons" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 +msgid "Select visible &columns in library view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 +msgid "Add a directory to the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 +msgid "Remove a directory from the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 +msgid "Free unused diskspace from the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 +msgid "&Compact database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 +msgid "&Metadata from file name" +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:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 +msgid "Author(s)" +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:31 +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:97 +msgid "Choose the format to convert into LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:105 +msgid "Convert %s to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 +msgid "Set conversion defaults" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 +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:256 +msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:257 +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:258 +msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +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:292 +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:293 +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:303 +msgid "<font color=\"gray\">No help available</font>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:404 +msgid "Bulk convert ebooks to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +msgid "Convert to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +msgid "Category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +msgid "Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid "Base &font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +msgid " pts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 +msgid "Embedded Fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +msgid "&Serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 +msgid "S&ans-serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 +msgid "&Monospace:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +msgid "Minimum &indent:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +msgid "&Word spacing:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +msgid "Enable auto &rotation of images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +msgid "Insert &blank lines between paragraphs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "Ignore &tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +msgid "Ignore &colors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Preprocess:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +msgid "Header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Show header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +msgid "&Header format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "Override<br>CSS" +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:552 +#: /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:556 +msgid " px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +msgid "&Convert tables to images (good for large/complex tables)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +msgid "&Multiplier for text size in rendered tables:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +msgid "Title based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 +msgid "&Disable chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 +msgid "&Regular expression:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 +msgid "Add &chapters to table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +msgid "Don't add &links to the table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 +msgid "Tag based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +msgid "&Page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 +msgid "&Force page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 +msgid "Force page break before &attribute:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 +msgid "Detect chapter &at tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 +msgid "Help on item" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 +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; font-" +"family:'Sans Serif'; font-size:9pt;\"></p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:114 +msgid "Edit Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +msgid "Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 +msgid "Author S&ort: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 +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:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +msgid "&Rating:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 +msgid "Rating of this book. 0-5 stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +msgid " stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 +msgid "Add Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +msgid "Open Tag Editor" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 +msgid "&Remove tags:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 +msgid "Comma separated list of tags to remove from the books. " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 +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:284 +msgid "<b>Could not fetch cover.</b><br/>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 +msgid "Could not fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "Cannot fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "You must specify the ISBN identifier for this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +msgid "Edit Meta Information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 +msgid "Swap the author and title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 +msgid "Fetch metadata from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 +msgid "Available Formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 +msgid "Add a new format for this book to the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +msgid "Remove the selected formats for this book from the database." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +msgid "Fetch cover image from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +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:317 +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/password_ui.py:57 +msgid "&Username:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 +msgid "&Password:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 +msgid "&Show password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:15 +msgid "Author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:17 +msgid "Tag" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Series" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 +msgid "Format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:21 +msgid "Any" +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:73 +msgid "Advanced Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:74 +msgid "Match a&ll of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:75 +msgid "Match a&ny of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:76 +msgid "Search criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:77 +msgid "More" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:78 +msgid "Fewer" +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:63 +msgid "No recipe selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 +msgid "The attached file: %s is a recipe to download %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 +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:214 +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 +msgid "Switch to Basic mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 +msgid "Feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:111 +msgid "The feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 +msgid "Feed must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:116 +msgid "The feed %s must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 +msgid "Already exists" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:122 +msgid "This feed has already been added to the recipe" +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:195 +msgid "Invalid input" +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:196 +msgid "<p>Could not create recipe. Error:<br>%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 +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:202 +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:188 +msgid "Choose a recipe file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:188 +msgid "Recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:208 +msgid "Add custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:209 +msgid "Available user recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:210 +msgid "Add/Update &recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:211 +msgid "&Remove recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:212 +msgid "&Share recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:213 +msgid "&Load recipe from file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 +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:219 +msgid "Recipe &title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:220 +msgid "&Oldest article:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:221 +msgid "The oldest article to download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:222 +msgid " days" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:223 +msgid "&Max. number of articles per feed:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:224 +msgid "Maximum number of articles to download per feed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:225 +msgid "Feeds in recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:227 +msgid "Remove feed from recipe" +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:233 +msgid "Add feed to recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:231 +msgid "&Feed title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:232 +msgid "Feed &URL:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:234 +msgid "&Add feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:235 +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:236 +msgid "Recipe source code (python)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 +msgid "" +"<p>Set a regular expression pattern to use when trying to guess ebook " +"metadata from filenames. <p>A <a href=\"http://docs.python.org/lib/re-" +"syntax.html\">reference</a> on the syntax of regular expressions is " +"available.<p>Use the <b>Test</b> functionality below to test your regular " +"expression on a few sample filenames." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:98 +msgid "Regular &expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:99 +msgid "&Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:100 +msgid "File &name:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:101 +msgid "Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:102 +msgid "Title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:103 +msgid "Regular expression group name (?P<title>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:107 +#: /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/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:105 +msgid "Authors:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 +msgid "Regular expression group name (?P<authors>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 +msgid "Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 +msgid "Regular expression group name (?P<series>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 +msgid "Series index:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 +msgid "Regular expression group name (?P<series_index>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 +msgid "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:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 +msgid "Cannot kill job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 +msgid "None" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +msgid "Book <font face=\"serif\">%s</font> of %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 +msgid "Double click to <b>edit</b> me<br><br>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 +msgid "Size (MB)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 +msgid "Date" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 +msgid "Rating" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 +msgid "Timestamp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 +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 +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 +msgid "Back" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:134 +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 +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:85 +msgid "Error communicating with device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 +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:99 +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:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +msgid "Send to main memory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "Send to storage card" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "and delete from library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 +msgid "Send to storage card by default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +msgid "Edit metadata individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +msgid "Edit metadata in bulk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 +msgid "Add books from a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 +msgid "" +"Add books recursively (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:141 +msgid "" +"Add books recursively (Multiple books per directory, assumes every ebook " +"file is a different book)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 +msgid "Save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 +msgid "Save to disk in a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +msgid "Save only %s format to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 +msgid "View" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 +msgid "View specific format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +msgid "Convert individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +msgid "Bulk convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 +msgid "Set defaults for conversion of comics" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 +msgid "Device: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 +msgid "Connected " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 +msgid "Device database corrupted" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 +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:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 +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:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 +msgid "Duplicates found!" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 +msgid "Uploading books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 +msgid "No space on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 +msgid "" +"<p>Cannot upload books to device there is no more free space available " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 +msgid "Confirm delete" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 +msgid "Are you sure you want to delete these %d books?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 +msgid "Deleting books from device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +msgid "Cannot edit metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "No books selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 +msgid "Sending books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 +msgid "No suitable formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 +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:758 +msgid "Cannot save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 +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:773 +msgid "Could not save some ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 +msgid "Fetching news from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 +msgid "News fetched. Uploading to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +msgid "No book selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 +msgid "Cannot view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 +msgid "Choose the format to view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 +msgid "%s has no available formats." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure while there are running jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +msgid "Invalid database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 +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:1041 +msgid "Could not move database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 +msgid "No detailed info available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 +msgid "No detailed information is available for books on the device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 +msgid "Error talking to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 +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:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 +msgid "Conversion Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 +msgid "Database does not exist" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 +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:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 +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:1216 +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:1216 +msgid "Update available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +msgid "calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +msgid "Advanced search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +msgid "Alt+S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +msgid "&Search:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +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:277 +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:278 +msgid "Reset Quick Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 +msgid "Add books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 +msgid "A" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 +msgid "Remove books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 +msgid "Del" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 +msgid "Edit meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 +msgid "E" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 +msgid "Send to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 +msgid "S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 +msgid "Fetch news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 +msgid "F" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 +msgid "Convert E-books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 +msgid "C" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 +msgid "V" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:17 +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 +msgid "ERROR: Unhandled exception" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:32 +msgid "Add a custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 +msgid "" +"<p>Please enter your username and password for %s<br>If you do not have one, " +"please subscribe to get access to the articles.<br/> Click OK to proceed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 +msgid "Custom news sources" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +msgid "Jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 +msgid "Click to see list of active jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to browse books by their covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to turn off Cover Browsing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 +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:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:178 +msgid "Library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 +msgid "" +"Reader\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 +msgid "" +"Card\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 +msgid "Click to see the list of books available on your computer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 +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:186 +msgid "Click to see the list of books on the storage card in your reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 +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:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 +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:94 +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" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +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:98 +msgid "Sort results in ascending order" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 +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:106 +msgid "Invalid fields. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 +msgid "Invalid sort field. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 +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:201 +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:210 +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:212 +msgid "Process directories recursively" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 +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:219 +msgid "You must specify at least one file to add" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 +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:249 +msgid "You must specify at least one book to remove" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 +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:280 +msgid "You must specify an id and an ebook file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 +msgid "ebook file must have an extension" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 +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:306 +msgid "You must specify an id and a format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 +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:332 +msgid "Print metadata in OPF form (XML)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 +msgid "You must specify an id" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 +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:364 +msgid "You must specify an id and a metadata file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 +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:384 +msgid "Export all books in database, ignoring the list of ids." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 +msgid "Export books to the specified directory. Default is" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 +msgid "Export all books into a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 +msgid "Create file names as author - title instead of title - author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 +msgid "You must specify some ids or the %s option" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 +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:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 +msgid "Could not launch worker process." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 +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:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77 +msgid "Unknown feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:95 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:117 +msgid "Untitled article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 +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:86 +msgid "" +"Options to control web2disk (used to fetch websites linked from feeds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 +msgid "Dont show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 +msgid "Fetching feeds..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 +msgid "Unknown News Source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 +msgid "Download finished" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 +msgid "Failed to download the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 +msgid " from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 +msgid "Failed to download parts of the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 +msgid "\tFailed links:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 +msgid "Could not fetch article. Run with --debug to see the reason" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 +msgid "Got feeds from index page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 +msgid "Trying to download cover..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +msgid "Starting download [%d thread(s)]..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 +msgid "Feeds downloaded to %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 +msgid "Could not download cover: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 +msgid "Downloading cover from %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 +msgid "Untitled Article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 +msgid "" +"\n" +"Downloaded article %s from %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 +msgid "Article downloaded: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 +msgid "Failed to download article: %s from %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 +msgid "Article download failed: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 +msgid "Fetching feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 +msgid "" +"%prog URL\n" +"\n" +"Where URL is for example http://google.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 +msgid "Base directory into which URL is saved. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +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:408 +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:419 +msgid "Show detailed output information. Useful for debugging" +msgstr "" diff --git a/src/calibre/translations/it.po b/src/calibre/translations/it.po index c60257f5d5..b09783a7ba 100644 --- a/src/calibre/translations/it.po +++ b/src/calibre/translations/it.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: it\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-08-01 22:06+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-22 13:36+0000\n" "Last-Translator: Iacopo Benesperi <Unknown>\n" "Language-Team: italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" @@ -69,9 +69,22 @@ msgstr "" #~ msgid "The author whoose book to search for." #~ msgstr "L'autore del libro da cercare" +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "&Posizione del database dei libri (library1.db)" + #~ msgid "&Access Key;" #~ msgstr "&Chiave d'accesso;" +#~ msgid "" +#~ "Cannot kill jobs that are communicating with the device as this may cause " +#~ "data corruption." +#~ msgstr "" +#~ "Impossibile terminare i lavori che stanno comunicando col dispositivo dato " +#~ "che potrebbe causare una corruzione dei dati" + +#~ msgid "Cannot kill already completed jobs." +#~ msgstr "Impossibile terminare i lavori già completati" + #~ msgid "Cannot kill waiting jobs." #~ msgstr "Impossibile terminare i lavori in attesa" @@ -88,14 +101,73 @@ msgstr "" #~ "Salvare il testo sottostante in un file di nome recipe.py e mandaro ai " #~ "propri amici, in modo da permettergli di usare questa formula." +#~ msgid "Copying database to " +#~ msgstr "Copiatura database in " + +#~ msgid "" +#~ "Path to the calibre database. Default is to use the path stored in the " +#~ "settings." +#~ msgstr "" +#~ "Percorso al database di calibre. L'opzione predefinita è quella di usare il " +#~ "percorso salvato nelle opzioni." + +#~ msgid "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "List the books available in the calibre database. \n" +#~ msgstr "" +#~ "%prog list [opzioni]\n" +#~ "\n" +#~ "Mostra un elenco dei libri disponibili nel database di calibre. \n" + +#~ 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 "" +#~ "%prog add [opzioni] file1 file2 file3 ...\n" +#~ "\n" +#~ "Aggiunge i file specificati nel database. È possibile anche specificare " +#~ "cartelle, leggere\n" +#~ "le opzioni dedicate alle cartelle in basso. \n" + +#~ 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 "" +#~ "%%prog comando [opzioni] [argomenti]\n" +#~ " %s\n" +#~ " \n" +#~ "Per aiuto su un singolo comando: %%prog comando --help\n" + +#~ 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\". Default is %default" +#~ msgstr "" +#~ "Individua l'inizio di un capitolo con un tag che ha l'attributo specificato. " +#~ "Il formato di questa opzione è regexp nome tag,nome attributo,regexp valore " +#~ "attributo. Ad esempio per far corrispondere tutti i tag di intestazione che " +#~ "hanno l'attributo class=\"capitolo\", bisogna usare \"h\\d,class,capitolo\". " +#~ "Predefinito: %default" + #~ 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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -105,53 +177,424 @@ msgstr "" #~ "<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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sUso%s: %s\n" +#~ 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 "" +#~ "\n" +#~ "%prog show_metedata [opzioni] id\n" +#~ "\n" +#~ "Mostra i metedati salvati nel database di calibre per il libro identificato " +#~ "da id. \n" +#~ "id è un numero id dalla lista dei comandi. \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Creato da " +#~ 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 "" +#~ "\n" +#~ "%prog set_metadata [opzioni] id /percorso/a/metadati.opf\n" +#~ "\n" +#~ "Imposta i metadati salvati nel database di calibre per il libro identificato " +#~ "da id\n" +#~ "presi dal file OPF metadati.opf. id è un numero id dalla lista dei comandi. " +#~ "È \n" +#~ "possibile farsi un'idea generale del formato OPF usando il parametro --as-" +#~ "opf\n" +#~ "nel comando show_metadata.\n" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ 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 "" +#~ "%prog export [opzioni] id \n" +#~ "\n" +#~ "Esporta i libri specificati da id (lista separata da virgole) nel " +#~ "filesystem.\n" +#~ "L'operazione di esportazione salva tutti i formati del libro, la sua " +#~ "copertina\n" +#~ "e i metadati (in un file opf). È possibile prendere i dumeri di id dalla " +#~ "lista dei comandi. \n" + +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "" +#~ "%prog [opzioni] comic.cb[z|r]\n" +#~ "\n" +#~ "Converte un fumetto di file CBZ o CBR in un libro LRF. \n" + +#~ msgid "Set defaults for conversion to LRF" +#~ msgstr "Imposta i parametri predefiniti per la conversione in LRF" + +#~ msgid "Convert comic %d of %d (%s)" +#~ msgstr "Conversione fumetto %d di %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "Impossibile individuare il disco %s. Provare a riavviare." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "Il lettore non ha una scheda di memoria connessa." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Opzioni per controllare la conversione in EPUB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"Il file EPUB in uscita. Se non viene specificato, viene ricavato dal nome " +"del file in ingresso." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "Controlla il rilevamento automatico della struttura del documento." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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 "" +"Controlla la generazione automatica del sommario.\n" +"Se viene rilevato un file OPF che specifica il sommario,\n" +"verrà usato quello del file invece di tentarne l'auto-rilevazione.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "Non aggiungere i capitoli rilevati automaticamente al sommario." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Sconosciuto" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 "" +"%prog [opzioni] file.html|opf\n" +"\n" +"Converte un file HTML in un libro EPUB. Segue ricorsivamente i collegamenti " +"nel file HTML.\n" +"Se si specifica un file OPF invece di uno HTML, la lista dei collegamenti " +"viene presa\n" +"dall'elemento <spine> del file OPF. \n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "È necessario specificare un file HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "HTML processato scritto in " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "Cartella in uscita. Predefinita: cartella corrente" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" +"Codifica caratteri per i file HTML. Predefinito: rilevamento automatico." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Crea l'output in un file zip. Se questa opzione è specificata, --output " +"dovrebbe essere il nome di un file, non di una cartella." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Controlla come vengono seguiti i collegamenti nei file HTML." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Massimo livello di ricorsività nel seguire i collegamenti in HTML. Deve " +"essere un numero non negativo. 0 significa che i collegamenti non vengono " +"seguiti." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Impostare i metadati del libro generato" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Impostare il titolo. Predefinito: rilevato automaticamente." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "L'autore(i) del libro, sottoforma di un elenco separato da virgole." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Opzioni utili per il debugging" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" +"Rendere l'HTML in uscita \"ben stampato\", per una comprensione più facile " +"da parte dell'uomo" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "%prog [opzioni] FILELIT" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." -msgstr "Cartella in uscita. Predefinita: cartella corrente" +msgstr "Cartella in uscita. Predefinita: cartella corrente." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Utile per il debugging" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "Libro OEB creato in" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Imposta il titolo. Predefinito: nome del file" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -159,49 +602,34 @@ msgstr "" "Imposta l'autore. Autori multipli devono essere separati da una virgola. " "Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Sconosciuto" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Imposta il commento" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Imposta la categoria" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Chiave per la classificazione del titolo" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Chiave per la classificazione dell'autore" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Editore" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Percorso al file contenente l'immagine da usare come copertina" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -209,12 +637,12 @@ msgstr "" "Se esiste una copertina grafica individuata nel file di origine, usa quella " "invece della copertina specificata" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" "Nome del file in uscita. Il nome predefinito è preso dal file in ingresso" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -223,7 +651,7 @@ msgstr "" "Questa opzione è necessaria se il file HTML contiene tabelle molto grandi o " "complesse" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -233,27 +661,27 @@ msgstr "" "scalati in accordo. Questa opzione rende obsoleta l'opzione --font-delta e " "ha precedenza su quest'ultima. Per usare --font-delta, impostare questa a 0" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Abilita la rotazione automatica delle immagini che sono più larghe dello " "schermo" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" "Imposta lo spazio tra le parole in punti. Il valore predefinito è %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Separa i paragrafi con linee bianche" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "" "Aggiunge a tutte le pagine un'intestazione contenente il titolo e l'autore" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -261,7 +689,7 @@ msgstr "" "Imposta il formato dell'intestazione. %a verrà rimpiazzato dall'autore e %t " "dal titolo. L'impostazione predefinita è %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -269,7 +697,7 @@ msgstr "" "Sovrascrive il CSS. Può essere un percorso ad un foglio di stile CSS o una " "stringa. Se è una stringa, sarà interpretata come CSS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -279,7 +707,7 @@ msgstr "" "HTML devono essere aggiunti al file LRF. Il file OPF deve essere nella " "stessa cartella del file HTML principale" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -287,7 +715,7 @@ msgstr "" "Indentazione minima paragrafo (l'indentazione della prima riga di un " "paragrafo) in pt. Predefinita: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -297,7 +725,7 @@ msgstr "" "tra le linee di FONT_DELTA punti. FONT_DELTA può essere una frazione. Se " "FONT_DELTA è negativo, la grandezza dei caratteri verrà diminuita" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." @@ -305,7 +733,7 @@ msgstr "" "Trasforma tutto il contenuto in bianco e nero al posto dei colori " "specificati dall'HTML o dal CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -315,23 +743,23 @@ msgstr "" "determina parametri come la risoluzione e la dimensione dello schermo del " "dispositivo. Predefinito: %s. Profili supportati: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Margine sinistro della pagina. Predefinito: %default px" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Margine destro della pagina. Predefinito: %default px" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Margine superiore della pagina. Predefinito: %default px" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Margine inferiore della pagina. Predefinito: %default px" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -339,7 +767,7 @@ msgstr "" "Trasforma in immagini le tabelle di HTML (utile se il documento ha tabelle " "grandi o complesse)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -347,7 +775,7 @@ msgstr "" "Moltiplica la dimensione del testo nelle tabelle trasformate di questo " "fattore. Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -357,7 +785,7 @@ msgstr "" "0 significa che i link non vengono seguiti. Un valore negativo significa che " "i tag <a> vengono ignorati" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -365,15 +793,15 @@ msgstr "" "Un'espressione regolare. I tag <a> i cui href corrispondono verranno " "ignorati. Predefinita: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Non aggiungere link al sommario." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Previene l'individuazione automatica dei capitoli." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -381,20 +809,17 @@ msgstr "" "L'espressione regolare utilizzata per individuare i titoli dei capitoli. I " "titoli vengono cercati nei tag d'intestazione (H1-H6). Predefinita: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" -"Individua l'inizio di un capitolo con un tag che ha l'attributo specificato. " -"Il formato di questa opzione è regexp nome tag,nome attributo,regexp valore " -"attributo. Ad esempio per far corrispondere tutti i tag di intestazione che " -"hanno l'attributo class=\"capitolo\", bisogna usare \"h\\d,class,capitolo\". " -"Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -413,14 +838,14 @@ msgstr "" "degradano le prestazioni dell'LRF nel girare la pagina. Questa opzione viene " "perciò ignorata se la pagina corrente ha solo pochi elementi" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Forza un'interruzione di pagina prima dei tag i cui nomi corrispondono a " "questa espressione regolare" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -433,15 +858,15 @@ msgstr "" "tutti i tag intestazione che hanno l'attributo class=\"chapter\" bisogna " "usare \"h\\d,class,chapter\". Predefinita: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Aggiungi i capitoli individuati al sommario." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "Preprocessa i file HTML di Baen per migliorare i file LRF generati" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -449,11 +874,11 @@ msgstr "" "È necessario aggiungere questa opzione se si stanno processando file " "generati da pdftohtml, altrimenti la conversione non riuscirà" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Usare questa opzione sui file html0 di Book Designer" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -466,27 +891,27 @@ msgstr "" "nel girare le pagine. Ad esempio: --serif-family \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "La famiglia di caratteri con grazie da includere" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "La famiglia di caratteri senza grazie da includere" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "La famiglia di caratteri a spaziatura fissa da includere" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Dettagliato durante il processamento" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Converte in LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -494,7 +919,7 @@ msgstr "" "Minimizza l'uso di memoria al costo di un maggior tempo di processamento. " "Usare questa opzione se si è su una macchina a corto di memoria" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -506,7 +931,7 @@ msgstr "" "comune per i computer Windows è cp-1252. Un'altra scelta comune è utf-8. " "L'opzione predefinita è quella di provare ad indovinare la codifica" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -523,30 +948,36 @@ msgstr "" "archivio RAR o ZIP, cercando i libri dentro l'archivio.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Nessun file da convertire specificato" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "Trasformato %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "Fallito %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "" +"Opzioni per controllare la conversione dei file di fumetti (CBR, CBZ) in " +"libri" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "Titolo per il libro generato. Predefinito: nome del file." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" "Imposta l'autore nei metadati del libro generato. Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." @@ -554,34 +985,57 @@ msgstr "" "Percorso del file LRF in uscita. Predefinito: creazione del file nella " "cartella corrente." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -"Numero di colori per la conversione delle immagini in scala di grigi. " -"Predefinito: %default" +"Numero di colori per conversione immagine in scala di grigi. Predefinito: " +"%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" "Disabilita la normalizzazione dell'intervallo dei colori per le immagini " "(migliora il contrasto). Predefinito: falso." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" "Mantieni le proporzioni dell'immagine. Predefinito: riempimento dello " "schermo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "Disabilita maschera di nitidezza." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "Non dividere le immagini orizzontali in due immagini verticali" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Mantieni le proporzioni e scala l'immagine usando l'altezza dello schermo " +"come larghezza dell'immagine per la visualizzazione in orizzontale." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Usato per pubblicazioni da destra a sinistra come i manga. Provoca la " +"divisione di una pagina orizzontale in due pagine verticali orientate da " +"destra a sinistra." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." @@ -589,7 +1043,7 @@ msgstr "" "Non ordinare i file trovati nel fumetto alfabeticamente per nome. Usa invece " "l'ordine in cui sono stati aggiunti al fumetto." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" @@ -598,31 +1052,33 @@ msgstr "" "LRF. Predefinito: SONY PRS-500 con una risoluzione di 584x754 pixel. Le " "scelte sono %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." msgstr "" +"Sii dettagliato, utile per il debugging. Può essere specificato più volte " +"per dettagli maggiori." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "Non visualizzare la barra di progresso." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:378 +msgid "Output written to" +msgstr "Output scritto in" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 msgid "Rendering comic pages..." msgstr "Trasformazione pagine fumetto..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:334 -msgid "Output written to" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" "Usage: %prog [options] mybook.epub\n" @@ -635,7 +1091,7 @@ msgstr "" " \n" "%prog converte miolibro.epub in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -647,25 +1103,25 @@ msgstr "" "\n" "%prog converte miolibro.fb2 in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Invia l'HTML generato allo stdout ed esce" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "" "Mantieni i file HTML generati dopo aver completato la conversione in LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Opzioni per controllare il comportamento di feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Opzioni per controllare il comportamento di html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Scaricamento della formula fallito: " @@ -693,32 +1149,32 @@ msgstr "Sto processando %s" msgid "\tConverting to BBeB..." msgstr "\tConversione in BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Impossibile analizzare il file: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%S è un file vuoto" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "Analisi fallita del link %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "Impossibile aggiungere il link %s alla TOC" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Impossibile processare l'immagine %s. Errore: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "Impossibile processare la PNG interlacciata %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -726,14 +1182,14 @@ msgstr "" "Impossibile processare l'immagine: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" "Si è verificato un errore nel processamento della tabella: %s. Ignoro il " "codice della tabella" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -741,11 +1197,11 @@ msgstr "" "Tabella malformata:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "La tabella ha celle troppo larghe" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -753,19 +1209,19 @@ msgstr "" "È necessario prima salvare il sito web %s come un file HTML e poi eseguire " "html2lrf su di esso" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "Impossibile leggere l'immagine di copertina: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "Impossibile leggere da: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Processamento del file OPF fallito" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -783,7 +1239,7 @@ msgstr "" "che puntano a file locali. In questo modo è possibile\n" "usarlo per convertire un intero albero di file HTML" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -795,7 +1251,7 @@ msgstr "" "\n" "%prog converte miolibro.lit in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -803,27 +1259,27 @@ msgstr "" "%prog libro.lrf\n" "Converte un file LRF in un file LRS (XML codificato UTF-8)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Restituisce un file LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Analisi LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Creazione XML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS scritto in " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" msgstr "Impossibile leggere dal file della miniatura:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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." @@ -831,16 +1287,16 @@ msgstr "" "%prog [opzioni] file.lrs\n" "Compila un file LRS dentro un file LRF" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Percorso del file in uscita" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "Processamento dettagliato" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "Converte LRS in LRS, utile per il debugging" @@ -863,7 +1319,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Imposta il titolo del libro" @@ -880,7 +1336,7 @@ msgid "Set sort key for the author" msgstr "Imposta la chiave per la classificazione dell'autore" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "La categoria a cui questo libro appartiene. Es: Storia" @@ -928,22 +1384,22 @@ msgstr "" "\n" "%prog converte miolibro.mobi in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "Impossibile trovare pdftohtml, verificare che sia nel proprio PATH" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " non permette la copia del testo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" " è un PDF basato su immagini. È supportata solamente la conversione di PDF " "basati su testo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -955,7 +1411,7 @@ msgstr "" "\n" "%prog converte miolibro.pdf in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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." @@ -963,15 +1419,15 @@ msgstr "" "Percorso della cartella in uscita dove creare il file HTML. Predefinito: " "cartella corrente" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Più dettagliato" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "È necessario specificare un singolo file PDF" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -983,7 +1439,13 @@ msgstr "" "\n" "%prog converte miolibro.rtf in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -995,23 +1457,33 @@ msgstr "" "\n" "%prog converte miolibro.txt in miolibro.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Imposta gli autori" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Imposta il commento" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "Una lista separata da virgole di tag da impostare" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Uso:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "Uso: imp-meta file.imp" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Nessun nome file specificato" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -1036,23 +1508,23 @@ msgstr "" "isndb.com\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "Il codice ISBN del libro di cui si vogliono i metadati" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "L'autore del libro da cercare" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "Il titolo del libro da cercare" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "L'editore del libro da cercare" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1060,16 +1532,16 @@ msgstr "" "Impossibile scaricare la copertina perché il server è sovraccarico. " "Ritentare più tardi" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " non trovato" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "Errore server LibraryThing.com. Riprovare più tardi." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1094,96 +1566,223 @@ msgstr "Copertina salvata in" msgid "Usage: pdf-meta file.pdf" msgstr "Uso: pdf-meta-file.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Nessun nome file specificato" +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "Uso: rb-meta file.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [opzioni] miolibro.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "MOBI HTML raw salvato in" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Cartelle usate frequentemente" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "Inviare automaticamente al dispositivo i periodici scaricati" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "Formato da utilizzare per il salvataggio di singoli file sul disco" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Chiedi conferma prima di eliminare" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "Dimensione bottoni nella barra degli strumenti" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Mostra testo nei bottoni della barra degli strumenti" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Geometria della finestra principale" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Avverti quando è disponibile una nuova versione" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Usa numeri romani per i numeri delle serie" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" +"Numero di copertine da visualizzare nella modalità di sfogliatura copertine" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Parametri predefiniti per la conversione in LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Opzioni del lettore di libri LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Dispositivo non più collegato." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Ottieni informazioni sul dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Ottieni la lista dei libri del dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Invia metadati al dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "Carica %d libri nel dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Cancella libri dal dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Scarica libri dal dispositivo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Visualizza libro sul dispositivo" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Titolo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Commenti" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Percorso" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formati" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Dialogo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "EtichettaDiTesto" +#: /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 "Scegliere il formato" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" msgstr "" +"Imposta i parametri predefiniti per la conversione di fumetti (file CBR/CBZ)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" -msgstr "" +msgstr "mposta le opzioni per convertire %s" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" -msgstr "" +msgstr "&Titolo:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" -msgstr "" +msgstr "&Autore(i)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" -msgstr "" +msgstr "&Numero di colori:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Profilo:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" -msgstr "" +msgstr "Disabilita normali&zzazione" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" -msgstr "" +msgstr "Ma&ntieni proporzioni" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" -msgstr "" +msgstr "Disabilita masc&hera di nitidezza" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" +msgstr "&Orizzontale" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "&Non ordinare" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "&Da destra a sinistra" + +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -1194,53 +1793,57 @@ msgstr "Base" msgid "Advanced" msgstr "Avanzata" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "<br>Deve essere una cartella" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Percorso database non valido " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Percorso database non valido" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Deve essere una cartella" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Percorso database non valido " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "Percorso database non valido.<br>Impossibile scrivere su " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." -msgstr "Compattamento database. Poterbbe richiedere un po' di tempo" +msgstr "Compattazione database. Poterbbe richiedere un po' di tempo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." -msgstr "Compattamento..." +msgstr "Compattazione..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Configurazione" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "&Posizione del database dei libri (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Sfoglia per specificare una nuova posizione del database" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1248,43 +1851,43 @@ msgstr "Sfoglia per specificare una nuova posizione del database" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "&Usa numeri romani per i numeri delle serie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" "&Numero di copertine da visualizzare nella modalità di sfogliatura (richiede " "riavvio):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "&Visualizza un avvertimento quando è disponibile una nuova versione" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "&Chiedere conferma prima di eliminare i file" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "&Formato per salvataggio singolo file:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "Pri&orità per i lavori di conversione:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "&Timeout predefinito della rete:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" @@ -1292,59 +1895,76 @@ msgstr "" "Imposta il timeout predefinito per gli scaricamenti dalla rete (cioè ogni " "volta che si usa Internet per prelevare informazioni)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " secondi" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "Scegliere la ling&ua (richiede il riavvio):" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Barra degli strumenti" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Grande" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Media" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Piccola" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "&Dimensione bottoni nella barra degli strumenti" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "&Mostra testo nei bottoni della barra degli strumenti" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "&Selezionare le colonne visibili nella vista biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Cartelle usate frequentemente" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "Aggiunge una cartella alla lista delle cartelle usate frequentemente" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "Rimuove una cartella dalla lista delle cartelle usate frequentemente" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Libera lo spazio non utilizzato dal database" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "&Compatta database" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "&Metadati dal nome del file" @@ -1352,10 +1972,344 @@ msgstr "&Metadati dal nome del file" msgid "ERROR" msgstr "ERRORE" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Metadati" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Visualizzazione" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Imposta pagina" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Individuazione capitoli" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" +"Mette a punto in modo fine l'individuazione delle intestazioni dei capitoli " +"e delle sezioni" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "Seleziona copertina per " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Impossibile leggere" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Non si hanno i permessi per leggere il file: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Errore nella lettura del file" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Si è verificato un errore nella lettura del file: <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " non è un'immagine valida" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Impossibile convertire" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Nessun formato disponibile" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" +"Impossibile convertire %s perché questo libro non ha formati supportati" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Copertina del libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "Ca&mbia l'immagine di copertina:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "" +"Sfoglia per trovare un'immagine da usare come copertina per questo libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Usa copertina del file di &origine" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Titolo: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Cambia il titolo di questo libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "A&utore(i): " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Cambia l'autore di questo libro. Autori multipli devono essere separati da " +"una virgola" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "Classifica&zione autore:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Editore: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Cambia l'editore di questo libro" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "T&ag: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" +"I tag categorizzano un libro. Questo è particolarmente utile durante le " +"ricerche. <br><br>Possono essere qualsiasi parola o frase, separati da una " +"virgola" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Serie:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Lista di serie conosciute. È possibile aggiungere nuove serie" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Indice serie" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Libro " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "C&odifica sorgente:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "Margine &sinistro:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "Margine &destro:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "Margine s&uperiore:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "Margine i&nferiore:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Autore(i)" @@ -1447,35 +2401,6 @@ msgstr "Lavori attivi" msgid "&Stop selected job" msgstr "I&nterrompi il lavoro selezionato" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Metadati" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Visualizzazione" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Imposta pagina" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Individuazione capitoli" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Nessun formato disponibile" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" -"Impossibile convertire %s perché questo libro non ha formati supportati" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Scegliere il formato da convertire in LRF" @@ -1485,33 +2410,10 @@ msgid "Convert %s to LRF" msgstr "Converte %s in LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Impostazioni di conversione predefinite" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "Impossibile leggere" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "Non si hanno i permessi per leggere il file: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Errore nella lettura del file" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "<p>Si è verificato un errore nella lettura del file: <br /><b>" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " non è un'immagine valida" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1559,12 +2461,6 @@ msgstr "" "Specifica le impostazioni della pagina come i margini e la dimensione dello " "schermo del dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" -"Mette a punto in modo fine l'individuazione delle intestazioni dei capitoli " -"e delle sezioni" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">Nessun aiuto disponibile</font>" @@ -1573,283 +2469,157 @@ msgstr "<font color=\"gray\">Nessun aiuto disponibile</font>" msgid "Bulk convert ebooks to LRF" msgstr "Conversione in gruppo di libri in LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Converti in LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Categoria" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Opzioni" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Copertina del libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "Ca&mbia l'immagine di copertina:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" -"Sfoglia per trovare un'immagine da usare come copertina per questo libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Usa copertina del file di &origine" - -#: /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:263 -msgid "&Title: " -msgstr "&Titolo: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Cambia il titolo di questo libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "A&utore(i): " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Cambia l'autore di questo libro. Autori multipli devono essere separati da " -"una virgola" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "Classifica&zione autore:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Editore: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Cambia l'editore di questo libro" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "T&ag: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"<br><br>They can be any words or phrases, separated by commas." -msgstr "" -"I tag categorizzano un libro. Questo è particolarmente utile durante le " -"ricerche. <br><br>Possono essere qualsiasi parola o frase, separati da una " -"virgola" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Serie:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Lista di serie conosciute. È possibile aggiungere nuove serie" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Indice serie" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Libro " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "&Grandezza caratteri di base:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " pt" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Caratteri inclusi" -#: /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:531 msgid "&Serif:" msgstr "&Con grazie:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "&Senza grazie:" -#: /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:533 msgid "&Monospace:" msgstr "&Dimensione fissa:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -msgstr "C&odifica sorgente:" - -#: /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:535 msgid "Minimum &indent:" msgstr "I&ndentazione minima:" -#: /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:537 msgid "&Word spacing:" msgstr "Spaziat&ura caratteri:" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Abilita &rotazione automatica delle immagini" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "Ins&erisci linee bianche tra i paragrafi" -#: /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:541 msgid "Ignore &tables" msgstr "Ignora ta&belle" -#: /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:542 msgid "Ignore &colors" msgstr "Ignor&a colori" -#: /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:543 msgid "&Preprocess:" msgstr "&Preprocessamento:" -#: /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:544 msgid "Header" msgstr "Intestazione" -#: /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:545 msgid "&Show header" msgstr "&Mostra intestazione" -#: /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:546 msgid "&Header format:" msgstr "&Formato intestazione:" -#: /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:547 msgid "Override<br>CSS" msgstr "Sovrascrivi<br>CSS" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "Margine &sinistro:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " px" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "Margine &destro:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "Margine s&uperiore:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "Margine i&nferiore:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "&Converti tabelle in immagini (utile per tabelle grandi/complesse)" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" "&Moltiplicatore per la dimensione del testo nelle tabelle trasformate:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Individuazione basata sul titolo" -#: /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:560 msgid "&Disable chapter detection" msgstr "&Disabilita l'individuazione del capitoli" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "&Espressione regolare:" -#: /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:562 msgid "Add &chapters to table of contents" msgstr "Aggiungi i &capitoli al sommario" -#: /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:563 msgid "Don't add &links to the table of contents" msgstr "Non aggiungere li&nk al sommario" -#: /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:564 msgid "Tag based detection" msgstr "Individuazione basata sui tag" -#: /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:565 msgid "&Page break before tag:" msgstr "I&nterruzione di pagina prima del tag:" -#: /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:566 msgid "&Force page break before tag:" msgstr "&Forza interruzione di pagina prima del tag:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Forza interruzione di pagina prima dell'&attributo:" -#: /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:568 msgid "Detect chapter &at tag:" msgstr "Indi&vidua capitolo col tag:" -#: /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:569 msgid "Help on item" msgstr "Aiuto per l'elemento" -#: /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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1859,8 +2629,8 @@ msgstr "" "<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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1870,17 +2640,17 @@ msgid "Edit Meta information" msgstr "Modifica metadati" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Metadati" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "&Classificazione autore: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1889,19 +2659,19 @@ msgstr "" "esempio, Charles Dickens deve essere classificato come Dickens, Charles." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Giudizio:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Giudizio su questo libro. 0-5 stelle" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " stelle" @@ -1911,8 +2681,8 @@ msgstr "&Aggiungi tag: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Apri l'editor dei tag" @@ -1924,7 +2694,7 @@ msgstr "&Rimuovi tag:" msgid "Comma separated list of tags to remove from the books. " msgstr "Lista separata da virgole dei tag da rimuovere dal libro " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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> " @@ -1934,65 +2704,70 @@ msgstr "" "<br/>Se non se ne possiede uno, è possibile <a " "href='http://www.librarything.com'>registrarsi</a> gratuitamente!</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "<b>Impossibile scaricare la copertina</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "Impossibile scaricare la copertina" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "Impossibile scaricare la copertina" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "È necessario specificare il codice ISBN di questo libro" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Modifica metadati" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "Scambia titolo e autore" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "Rimuovi serie inutilizzate (che non hanno libri)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Scarica metadati dal server" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Formati disponibili" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Aggiungi un nuovo formato al database per questo libro" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "Rimuovi il formato selezionato dal database per questo libro" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Scarica immagine di copertina dal server" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" "Cambia il nome utente e/o password del proprio account su LibraryThing.com" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Cambia password" @@ -2021,13 +2796,15 @@ msgid "Tag" msgstr "Tag" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Serie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Formato" @@ -2359,11 +3136,11 @@ msgstr "Nome del gruppo per l'espressione regolare (?P< title>)" #: /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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "Nessuna corrispondenza" @@ -2396,103 +3173,102 @@ msgstr "Nome del gruppo per l'espressione regolare (?P<series_index>)" msgid "ISBN:" msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Lavoro" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Stato" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Progresso" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "Tempo di esecuzione" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "Errore" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "Lavoro sconosciuto" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "Finito" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Errore" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" msgstr "In attesa" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "In esecuzione" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "Impossibile terminare il lavoro" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." -msgstr "" -"Impossibile terminare i lavori che stanno comunicando col dispositivo dato " -"che potrebbe causare una corruzione dei dati" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "Impossibile annullare i processi che comunicano col dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "Impossibile terminare i lavori già completati" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "Il lavoro è già stato avviato" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "Impossibile uccidere il lavoro in attesa" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Nessuno" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Tag" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formati" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Libro <font face=\"serif\">%s</font> di %s" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "Doppio clic per <b>modificarmi</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Dimensione (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Data" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Giudizio" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Percorso" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Timestamp" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "Cerca (Per la ricerca avanzata fare clic sul bottone a sinistra)" @@ -2512,15 +3288,15 @@ msgstr "Unisci" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "<b>Le modifiche avranno effetto dopo il riavvio.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" msgstr " - Lettore LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "<b>Nessuna corrispondenza</b> trovata per la frase <i>%s</i>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "Nessuna corrispondenza trovata" @@ -2564,11 +3340,11 @@ msgstr "Apri libro" msgid "Configure" msgstr "Configurazione" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Errore di comunicazione col dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" @@ -2576,42 +3352,42 @@ msgstr "" "<p>Per aiuto visitare <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "<b>%s</b>: %s di <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "Invia alla memoria principale" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "Invia alla scheda di memoria" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "e elimina dalla libreria" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "Invia alla scheda di memoria come imposazione predefinita" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Modifica metadati individualmente" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Modifica metadati in gruppo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "Aggiungi libri da una singola cartella" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2619,7 +3395,7 @@ msgstr "" "Aggiungi libri ricorsivamente (un libro per cartella, assume che ogni file " "sia lo stesso libro in un diverso formato)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2627,61 +3403,75 @@ msgstr "" "Aggiungi libri ricorsivamente (più libri per cartella, assume che ogni file " "sia un libro diverso)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Salva su disco" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "Salva su disco in una singola cartella" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "Salva sul disco solo il formato %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Leggi" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "Leggi uno specifico formato" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Converti individualmente" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Converti in gruppo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" +msgstr "Imposta i parametri predefiniti per la conversione di fumetti" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr " individuato." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "Scegliere un percorso per la propria libreria." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "Esportazione database" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "Dispositivo: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " individuato." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "Connesso " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "Database del dispositivo corrotto" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2710,8 +3500,8 @@ msgstr "" " </ol>\n" " " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2719,60 +3509,60 @@ msgstr "" "<p>Nel database sono già presenti libri con i seguenti titoli. Aggiungerli " "ugualmente?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "Scoperti duplicati!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "Caricamento libri nel dispositivo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Spazio insufficiente sul dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>Impossibile salvare libri sul dispositivo perché non c'è più spazio " "disponibile " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "Conferma elininazione" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "Si è sicuri di voler eliminare questi %d libri?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "Cancellamento libri dal dispositivo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "Impossibile modificare i metadati" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Nessun libro selezionato" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "Invio libri al dispositivo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "Nessun formato adatto" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" @@ -2780,11 +3570,11 @@ msgstr "" "Impossibile caricare i seguenti libri nel dispositivo, perché non è stato " "trovato nessun formato adatto:<br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "Impossibile salvare sul disco" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" @@ -2792,93 +3582,60 @@ msgstr "" "<p>Impossibile salvare i libri seguenti su disco, perché il formato %s non è " "disponibile per loro:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "Impossibile salvare alcuni libri" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "Scarica notizie da " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "Scaricamento notizie da " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "Notizie scaricate. Salvataggio sul dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "Impossibile convertire" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "Avviamento conversione in gruppo di %d libri" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Nessun libro selezionato" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "Impossibile leggere" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "Scegliere il formato da leggere" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "%s non ha formati disponibili" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "Impossibile configurare" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "Impossibile configurare mentre ci sono lavori in esecuzione" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "Copiatura database in " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "Copia biblioteca in " + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "Database non valido" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2886,25 +3643,25 @@ msgstr "" "<p>Esiste già un database non valido in %s, eliminarlo prima di provare a " "spostare il database esistente.<br>Errore: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "Impossibile spostare il database" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "Nessuna informazione dettagliata disponibile" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" "Non è disponibile alcuna informazione dettagliata per i libri nel " "dispositivo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Errore di comunicazione col dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2912,15 +3669,16 @@ msgstr "" "Si è verificato un errore di comunicazione temporaneo col dispositivo. " "Disconnettere e riconnettere il dispositivo e/o riavviare" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "Errore di conversione" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "Il database non esiste" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." @@ -2928,7 +3686,11 @@ msgstr "" "La cartella in cui il database dovrebbe essere: %s non esiste più. Scegliere " "una nuova posizione per il database." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "Selezionare una nuova posizione per il database" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" @@ -2936,7 +3698,7 @@ msgstr "" "<span style=\"color:red; font-weight:bold\">Ultima versione: <a " "href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " @@ -2946,27 +3708,27 @@ msgstr "" "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">nuove " "funzionalità</a>. Una visita alla pagina del download?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "Aggiornamento disponibile" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "Ricerca avanzata" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Cerca:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -2974,7 +3736,7 @@ msgstr "" "Cerca nella lista dei libri per titolo o autore<br><br>Parole separate da " "spazi hanno come operatore AND" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -2982,60 +3744,68 @@ msgstr "" "Cerca nella lista dei libri per titolo, autore, editore, tag e " "commenti<br><br>Parole separate da spazi hanno come operatore AND" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Resetta ricerca veloce" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Aggiungi libri" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Rimuovi libri" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Canc" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Modifica metadati" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "Invia al dispositivo" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Scarica notizie" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "F" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "Converti libri" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "C" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "V" @@ -3047,7 +3817,7 @@ msgstr "" "Redireziona l'output della console a una finestra di dialogo (sia stdout ceh " "stderr). Utile nelle finestre dove l'applicazione GUI non ha un output." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "ERRORE: eccezione non gestita" @@ -3068,23 +3838,23 @@ msgstr "" msgid "Custom news sources" msgstr "Fonti di notizie personalizzate" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Lavori:" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "Fare clic per vedere una lista dei lavori attivi" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "Fare clic per sfogliare i libri per copertine" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "Fare clic per disattivare la navigazione per copertina" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" @@ -3092,19 +3862,71 @@ msgstr "" "<p>La navigazione per copertina è disabilitata.<br>Caricamento del modulo " "pictureflow fallito:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "Conversione libro: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "Conversione fumetto: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Avviamento conversione in gruppo di %d libri" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "Conversione libro %d di %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" +"<p>Impossibile convertire %d di %d libri, perché non è stato trovato un " +"formato di origine adatto.<ul>%s</ul>" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "Impossibile convertire alcuni libri" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Scarica notizie da " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" msgstr "Espressione regolare non valida" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" msgstr "Espressione regolare non valida: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Biblioteca" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3112,7 +3934,7 @@ msgstr "" "Lettore\n" "%s disponibili" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3120,42 +3942,44 @@ msgstr "" "Scheda\n" "%s disponibili" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" "Fare clic per vedere la lista di libri disponibili sul proprio computer" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "" "Fare clic per vedere la lista di libri nella memoria principale del proprio " "lettore" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" "Fare clic per vedere la lista di libri nella scheda di memoria del proprio " "lettore" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" -"Percorso al database di calibre. L'opzione predefinita è quella di usare il " -"percorso salvato nelle opzioni." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" "%prog list [opzioni]\n" "\n" -"Mostra un elenco dei libri disponibili nel database di calibre. \n" +"Elenca i libri disponibili nel database di calibre.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3167,7 +3991,7 @@ msgstr "" "Campi disponibili: %s\n" "Predefinito: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" @@ -3177,11 +4001,11 @@ msgstr "" "Campi disponibili: %s\n" "Predefinito: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "Ordina i risultati in ordine crescente" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 " @@ -3191,15 +4015,15 @@ msgstr "" "documentazione relativa alla ricerca nel Manuale Utente. L'opzione " "predefinita è quella di non filtrare." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "Campi non validi. Campi disponibili:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "Campo per l'ordinamento non valido. Campi disponibili:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" @@ -3207,21 +4031,16 @@ msgstr "" "I seguenti libri non sono stati aggiunti perché già esistenti nel database " "(vedere l'opzione --duplicates):" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -"%prog add [opzioni] file1 file2 file3 ...\n" -"\n" -"Aggiunge i file specificati nel database. È possibile anche specificare " -"cartelle, leggere\n" -"le opzioni dedicate alle cartelle in basso. \n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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" @@ -3229,21 +4048,21 @@ msgstr "" "Assume che ogni cartella abbia un solo libro logico e che tutti i file " "presenti siano diversi formati per quel libro" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "Processa cartelle ricorsivamente" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." msgstr "Aggiunge libri al database anche se esistono già." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "È necessario specificare almeno un file da aggiungere" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3257,11 +4076,11 @@ msgstr "" "separata da virgole di numeri id (è possibile ottenere i numeri id usando il " "comando list). Ad esempio: 23,34,57-85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "È necessario specificare almeno un libro da aggiungere" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3275,15 +4094,15 @@ msgstr "" "identificato da id. È possibile ottenere gli id usando il comando list. Se " "il formato esiste già, verrà sovrascritto.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "È necessario specificare un id e un file ebook" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "I file ebook devono avere un'estensione" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3300,35 +4119,29 @@ msgstr "" "file come LRF, TXT o EPUB. Se il libro logico non ha un fmt disponibile, non " "fa niente.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "È necessario specificare un id e un formato" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -"\n" -"%prog show_metedata [opzioni] id\n" -"\n" -"Mostra i metedati salvati nel database di calibre per il libro identificato " -"da id. \n" -"id è un numero id dalla lista dei comandi. \n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "Stampa i metafati in formato OPF (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "È necessario specificare un id" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3336,85 +4149,116 @@ msgid "" "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" +"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 "" -"\n" -"%prog set_metadata [opzioni] id /percorso/a/metadati.opf\n" -"\n" -"Imposta i metadati salvati nel database di calibre per il libro identificato " -"da id\n" -"presi dal file OPF metadati.opf. id è un numero id dalla lista dei comandi. " -"È \n" -"possibile farsi un'idea generale del formato OPF usando il parametro --as-" -"opf\n" -"nel comando show_metadata.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "È necessario specificare un id e un file di metadati" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" -"%prog export [opzioni] id \n" -"\n" -"Esporta i libri specificati da id (lista separata da virgole) nel " -"filesystem.\n" -"L'operazione di esportazione salva tutti i formati del libro, la sua " -"copertina\n" -"e i metadati (in un file opf). È possibile prendere i dumeri di id dalla " -"lista dei comandi. \n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "Esporta tutti i libri del database, ignorando la lista di id." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "Esporta i libri nella cartella specificata. Predefinita:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "Esporta tutti i libri in una singola cartell" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" "Crea i nomi dei file come \"autore - titolo\" invece di \"titolo - autore\"" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "È necessario specificare qualche id o l'opzione %s" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -"%%prog comando [opzioni] [argomenti]\n" -" %s\n" -" \n" -"Per aiuto su un singolo comando: %%prog comando --help\n" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "Compattazione database" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "Impossibile avviare il gestore dei lavori." +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sUso%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Creato da " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "Percorso del database in cui sono salvati i libri" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "Impossibile inizializzare la libreria fontconfig" @@ -3445,7 +4289,153 @@ msgstr "Feed sconosciuto" msgid "Untitled article" msgstr "Articolo senza titolo" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Timeout in secondi da aspettare per una risposta dal server. Predefinito: " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Intervallo minimo in secondi tra due scaricamenti consecutivi. Predefinito: " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"La codifica caratteri del sito webb che si sta cercando di scaricare. " +"L'impostazione predefinita è quella di provare a indovinare la codifica" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Verranno seguiti solamente i link che corrispondono a questa espressione " +"regolare. Questa opzione può essere specificata più volte, in questo modo se " +"un link corrisponde a una delle espressioni regolari verrà seguito. Per " +"impostazione predefinita i link non vengono seguiti" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Tutti i link che corrispondono a questa espressione regolare saranno " +"ignorati. Questa opzione può essere specificata più volte, in questo modo " +"finché una regexp fa corrispondere un link, questo sarà ignorato. Per " +"impostazione predefinita nessun link viene ignorato. Se vengono specificate " +"sia --filter-regexp che --match-regexp, --filter-regexp viene applicata per " +"prima" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Non scaricare i fogli di stile CSS" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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 "" +"Specificare una lista di feed da scaricare. Per esempio: \n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"Se si specifica questa opzione, ogni indice per %prog viene ignorato e viene " +"usata una formula predefinita per scaricare i feed." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "Più dettagliato durante il processamento" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"Il titolo per questa formula. Usato come titolo per ogni libro creato da " +"questi feed scaricati" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" +"Nome utente per i siti che richiedono un'identificazione per accedere ai " +"contenuti" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" +"Password per i siti che richiedono un'identificazione per accedere ai " +"contenuti" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Numero di livelli di link da seguire nelle pagine web che sono collegate ai " +"feed. Predefinito: %default" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"La cartella in cui salvare i feed scaricati. Perdefinita: cartella corrente" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "Output molto dettagliato, utile per il debugging" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Utile per lo sviluppo delle formule. Forza max_articles_per_feed a 2 e " +"scarica al massimo 2 feed" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3484,146 +4474,81 @@ msgstr "" "Le formule presenti disponibili sono:\n" "%s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" "Opzioni per controllare web2disk (usato per scaricare i siti collegati ai " "feed)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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 "" -"Specificare una lista di feed da scaricare. Per esempio: \n" -"\"['http://feeds.newsweek.com/newsweek/TopNews', " -"'http://feeds.newsweek.com/headlines/politics']\"\n" -"Se si specifica questa opzione, ogni indice per %prog viene ignorato e viene " -"usata una formula predefinita per scaricare i feed." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 -msgid "Be more verbose while processing." -msgstr "Più dettagliato durante il processamento" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -msgid "" -"The title for this recipe. Used as the title for any ebooks created from the " -"downloaded feeds." -msgstr "" -"Il titolo per questa formula. Usato come titolo per ogni libro creato da " -"questi feed scaricati" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:47 -msgid "Username for sites that require a login to access content." -msgstr "" -"Nome utente per i siti che richiedono un'identificazione per accedere ai " -"contenuti" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" -"Password per i siti che richiedono un'identificazione per accedere ai " -"contenuti" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" -"Numero di livelli di link da seguire nelle pagine web che sono collegate ai " -"feed. Predefinito: %default" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "" -"The directory in which to store the downloaded feeds. Defaults to the " -"current directory." -msgstr "" -"La cartella in cui salvare i feed scaricati. Perdefinita: cartella corrente" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "Non mostrare la barra di progresso" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "Output molto dettagliato, utile per il debugging" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -msgid "" -"Useful for recipe development. Forces max_articles_per_feed to 2 and " -"downloads at most 2 feeds." -msgstr "" -"Utile per lo sviluppo delle formule. Forza max_articles_per_feed a 2 e " -"scarica al massimo 2 feed" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "Scaricamento feed..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "Sorgente di notizie sconosciuta" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "Scaricamento completato" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "Scaricamento dei seguenti articoli fallito:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr " da " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "Scaricamento dei seguenti articoli fallito parzialmente:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "\tLink falliti:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" "Impossibile scaricare l'articolo. Eseguire con --debug per vedere la ragione" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "Ricevuti feed dalla pagina principale" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "Tentativo di scaricamento della copertina..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "Inizio scaricamento [%d articolo(i)]..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "Feed scaricati in %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "Impossibile scaricare la copertina: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "Scaricamento copertina da %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "Articolo senza titolo" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" @@ -3633,23 +4558,23 @@ msgstr "" "Scaricato articolo %s da %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "Articolo scaricato: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "Scaricamento fallito dell'articolo: %s da %s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "Scaricamento fallito dell'articolo: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "Scaricamento feed" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" @@ -3659,19 +4584,11 @@ msgstr "" "\n" "Dov'è l'URL. Esempio: http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "Cartella base in cui le URL sono salvate. Predefinita: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Timeout in secondi da aspettare per una risposta dal server. Predefinito: " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3679,7 +4596,7 @@ msgstr "" "Numero massimo di livelli ricorsivi, cioè profondità dei link da seguire. " "Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3687,52 +4604,6 @@ msgstr "" "Il numero massimo di file da scaricare. Questa si applica solo ai file dai " "tag <a fref>. Predefinito: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Intervallo minimo in secondi tra due scaricamenti consecutivi. Predefinito: " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -msgid "" -"The character encoding for the websites you are trying to download. The " -"default is to try and guess the encoding." -msgstr "" -"La codifica caratteri del sito webb che si sta cercando di scaricare. " -"L'impostazione predefinita è quella di provare a indovinare la codifica" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:400 -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 "" -"Verranno seguiti solamente i link che corrispondono a questa espressione " -"regolare. Questa opzione può essere specificata più volte, in questo modo se " -"un link corrisponde a una delle espressioni regolari verrà seguito. Per " -"impostazione predefinita i link non vengono seguiti" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 -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 "" -"Tutti i link che corrispondono a questa espressione regolare saranno " -"ignorati. Questa opzione può essere specificata più volte, in questo modo " -"finché una regexp fa corrispondere un link, questo sarà ignorato. Per " -"impostazione predefinita nessun link viene ignorato. Se vengono specificate " -"sia --filter-regexp che --match-regexp, --filter-regexp viene applicata per " -"prima" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "Non scaricare i fogli di stile CSS" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "Mostra un output dettagliato. Utile per il debugging" diff --git a/src/calibre/translations/nb.po b/src/calibre/translations/nb.po new file mode 100644 index 0000000000..c2b8e65917 --- /dev/null +++ b/src/calibre/translations/nb.po @@ -0,0 +1,4076 @@ +# Norwegian Bokmal translation for calibre +# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008 +# This file is distributed under the same license as the calibre package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: calibre\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-19 20:41+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" +"Language-Team: Norwegian Bokmal <nb@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: 2008-10-06 00:28+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "" +#~ "%prog [opsjoner] tegneserie.cb[z|r]\n" +#~ "\n" +#~ "Konverterer en tegneserie i CBZ eller CBR formatet til en LRF digitalbok. \n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 +msgid "Unable to detect the %s disk drive. Try rebooting." +msgstr "Finner ikke %s lagringsenheten. Venligst prøv å restarte." + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 +msgid "The reader has no storage card connected." +msgstr "Lesebrettet har ikke et lagringskort tilknyttet seg." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Ukjent" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 +msgid "%prog [options] LITFILE" +msgstr "%applikasjon [opsjoner] LITFIL" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +msgid "Output directory. Defaults to current directory." +msgstr "Lagringskatalog. Standard er nåværende katalog" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" +"Uthentet markup fra lesbart format. Dette kan medføre at mellomrom, " +"tabulatorer og linjeskift blir modifisert." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 +msgid "Useful for debugging." +msgstr "Praktisk for feilsøking." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 +msgid "OEB ebook created in" +msgstr "OEB bok opprettet i" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +msgid "Set the title. Default: filename." +msgstr "Angi tittel. Standard: filnavn" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 +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:78 +msgid "Set the comment." +msgstr "Angi kommentar" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +msgid "Set the category" +msgstr "Angi kategori" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +msgid "Sort key for the title" +msgstr "Sorteringsnøkkel for tittel" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +msgid "Sort key for the author" +msgstr "Sorteringsnøkkel for forfatter" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 +msgid "Publisher" +msgstr "Forlag" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +msgid "Path to file containing image to be used as cover" +msgstr "Filstien til bokomslagsbildet" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 +msgid "" +"If there is a cover graphic detected in the source file, use that instead of " +"the specified cover." +msgstr "" +"Hvis et omslagsbilde blir oppdaget i kildefilen, vil det bli brukt fremfor " +"det spesifiserte omslagsbildet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +msgid "Output file name. Default is derived from input filename" +msgstr "" +"Utgående filnavn. Standard er at den blir avledet fra inngående filnavn." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 +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 "" +"Viser HTML tabeller som tekstblokker fremfor tabellvisning. Dette er " +"nødvendig hvis HTMLen inneholder store eller komplekse tabeller." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +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 "" +"Spesifiser standard font størrelse i prs. Alle fonter blir skalert i henhold " +"til denne. Denne opsjonen forelder --font-delta opsjonen og tar presedens " +"over den. For å bruke --font-delta, sett den til 0. Standard: %defaultpt" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 +msgid "Enable autorotation of images that are wider than the screen width." +msgstr "" +"Aktiver automatisk rotering av bilder som er bredere enn skjermbredden" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +msgid "Set the space between words in pts. Default is %default" +msgstr "Angi avstand mellom ordene i pts. Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +msgid "Separate paragraphs by blank lines." +msgstr "Separer paragrafer med tomme linjer" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +msgid "Add a header to all the pages with title and author." +msgstr "Angi topptekst til alle sidene med tittel og forfatter" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +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:111 +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 "" +"Overkjører gjeldende CSS. Kan enten være en filsti til en CSS fil eller en " +"streng. Hvis det er en streng, blir den tolket som CSS." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +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 "" +"Bruk <spine> elementet fra OPF filen for å bestemme hvilken rekkefølge HTML " +"filene skal legges til LRF filen. OPF filen må ligge i samme katalog som " +"basis HTML filen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +msgid "" +"Minimum paragraph indent (the indent of the first line of a paragraph) in " +"pts. Default: %default" +msgstr "" +"Minste paragraf indentering (indenteringen til den første linjen i en " +"paragraf) i pts. Standard: %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 +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 "" +"Øker fontstørrelsen med 2 * FONT_DELTA pts og linjeavstand med FONT_DELTA " +"pts. FONT_DELTA kan være en fraksjon. Hvis FONT_DELTA er negativ, så vil " +"fontstørrelsen minskes." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 +msgid "" +"Render all content as black on white instead of the colors specified by the " +"HTML or CSS." +msgstr "" +"Vis alt innhold som svart på hvitt i stedet for fargene spesifisert i HTML " +"eller CSS." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 +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 "" +"Profilen til lagringsenheten som denne LRF filen blir generert for. Profilen " +"angir innstillinger som oppløsning og skjerm størrelsen til lagringsenheten. " +"Standard: %s Støttede profiler: " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +msgid "Left margin of page. Default is %default px." +msgstr "Sidens venstremarg. Standard er %default px." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +msgid "Right margin of page. Default is %default px." +msgstr "Sidens høyremarg. Standard er %default px." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +msgid "Top margin of page. Default is %default px." +msgstr "Sidens toppmarg. Standard er %default px." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +msgid "Bottom margin of page. Default is %default px." +msgstr "Sidens bunnmarg. Standard er %default px." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +msgid "" +"Render tables in the HTML as images (useful if the document has large or " +"complex tables)" +msgstr "" +"Viser tabeller i HTML som bilder (praktisk hvis dokumentet har store eller " +"komplekse tabeller)" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 +msgid "" +"Multiply the size of text in rendered tables by this factor. Default is " +"%default" +msgstr "" +"Multipliserer størrelsen på teksten i tabeller med denne faktoren. Standard " +"er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 +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 "" +"Maks antall rekurserbare nivåer for å håndtere lenker. Nullverdi innebærer " +"at lenker ikke blir håndtert. En negativ verdi innebærer at <a> tagger blir " +"ignorert." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 +msgid "" +"A regular expression. <a> tags whose href matches will be ignored. Defaults " +"to %default" +msgstr "" +"Et regulært uttrykk. <a> tagger med matchende href attributt vil bli " +"ignorert. Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 +msgid "Don't add links to the table of contents." +msgstr "Ikke legg til lenker i innholdsregisteret." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 +msgid "Prevent the automatic detection chapters." +msgstr "Forhindre automatisk detektering av kapitler." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 +msgid "" +"The regular expression used to detect chapter titles. It is searched for in " +"heading tags (h1-h6). Defaults to %default" +msgstr "" +"Regulært uttrykk brukt for å detektere kapittel overskrifter. Det blir søkt " +"etter overskrift tagger (h1 - h6). Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +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:169 +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 "" +"Hvis det ikke finnes sideskift i HTML filen og kapittel overskrifter, så vil " +"html2lrf automatisk legge til sideskift før elementene som matcher det " +"regulære uttrykket. Standard er %default. Dette kan forhindres ved å sette " +"regexp til \"$\". Meningen bak denne opsjonen er å sikre at svært lange " +"sider ikke degraderer LRFs sideskifte ytelse. Denne opsjonen blir ignorert " +"hvis nåværende side har få elementer." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +msgid "" +"Force a page break before tags whose names match this regular expression." +msgstr "" +"Plasser sideskifte foran element navn som matcher det regulære uttrykket." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 +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 "" +"Plasserer et sideskifte foran elementer med det spesifiserte attributtet. " +"Formatet for denne opsjonen er elementnavn regexp, attributtnavn, " +"attributtverdi regexp. For å matche alle elementer med attributtet " +"class=\"chapter\" må man bruke \"h\\d,class,chapter\". Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 +msgid "Add detected chapters to the table of contents." +msgstr "Legg til oppdagede kapitler til innholdsregisteret." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +msgid "Preprocess Baen HTML files to improve generated LRF." +msgstr "" +"Førprosessere Baen HTML filer for å forbedre den genererte LRF filen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +msgid "" +"You must add this option if processing files generated by pdftohtml, " +"otherwise conversion will fail." +msgstr "" +"Hvis filene er generert med pdftohtml, må du legge til denne opsjonen for å " +"unngå at konverteringen feiler." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 +msgid "Use this option on html0 files from Book Designer." +msgstr "Bruk denne opsjonen på html0 filer fra Book Designer." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 +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 "" +"Angi trutype font familier for serif, sans-serif og monospace fonter. Disse " +"fontene vil bli lagret i LRF filen. NB: Ikke standard fonter kan føre til " +"tregere sideskifte. Eksempel: --serif-family \"Times New Roman\"\n" +" " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 +msgid "The serif family of fonts to embed" +msgstr "Serif font familie" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 +msgid "The sans-serif family of fonts to embed" +msgstr "Sans-serif font familie" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 +msgid "The monospace family of fonts to embed" +msgstr "Monospace font familie" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +msgid "Be verbose while processing" +msgstr "Vær informativ under prosesseringen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +msgid "Convert to LRS" +msgstr "Konverter til LRS" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +msgid "" +"Minimize memory usage at the cost of longer processing times. Use this " +"option if you are on a memory constrained machine." +msgstr "" +"Minimer minne bruken på bekostning av prosesseringstid. Bruk denne opsjonen " +"om maskinen har begrenset minne." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 +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 "" +"Spesifiser tegnkoden til kildefilen. Hvis utgående LRF filen inneholder " +"merkelige bokstaver, forsøk å endre denne opsjonen. En vanlig fil tegnkode " +"for Windows maskiner er cp-1252. utf-8 er også et vanlig valg. Vanlig " +"forsøks vinkel er å gjette tegnkoden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 +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 "" +"any2lrf [opsjoner] minfil\n" +"\n" +"Konverterer enhver ebok format til LRF. Støttede formater er:\n" +"LIT, RTF, TXT, HTML, EPUB, MOBI, PRC og PDF. any2lrf vil også håndtere RAR " +"eller ZIP arkiv ved å søke etter ebøker inni arkivet.\n" +" " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 +msgid "No file to convert specified." +msgstr "Ingen fil angitt for konvertering" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 +msgid "Rendered %s" +msgstr "Gjengitt %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 +msgid "" +"Options to control the conversion of comics (CBR, CBZ) files into ebooks" +msgstr "" +"Opsjoner for å kontrollere konverteringen av tegneserier (CBR, CBZ) filer " +"til digitale bøker." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 +msgid "Title for generated ebook. Default is to use the filename." +msgstr "Tittel for generert digitalbok. Standard er å bruke filnavnet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 +msgid "" +"Set the author in the metadata of the generated ebook. Default is %default" +msgstr "" +"Angi forfatter i metadataene til generert digitalbok. Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 +msgid "" +"Path to output LRF file. By default a file is created in the current " +"directory." +msgstr "" +"Filsti til utgående LRF fil. Standard er å opprette en fil i nåværende " +"katalog." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" +msgstr "" +"Antall farger brukt for gråskala bildekonvertering. Standard er %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 +msgid "" +"Disable normalize (improve contrast) color range for pictures. Default: False" +msgstr "" +"Forhindre normalisering (forbedre kontrasten) av farge rangering for bilder. " +"Standard: False" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 +msgid "Maintain picture aspect ratio. Default is to fill the screen." +msgstr "Beholde bilde sideforhold. Standard er å fylle hele skjermen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 +msgid "Disable sharpening." +msgstr "Ikke foreta skjerping av bilder" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 +msgid "Don't split landscape images into two portrait images" +msgstr "Ikke splitt landskapsbilder i to portrett bilder" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Brukt for høyre til venstre publikasjoner som manga. Innebærer at " +"landskapssider blir splittet til portrettbilder som leses fra høyre til " +"venstre." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 +msgid "" +"Don't sort the files found in the comic alphabetically by name. Instead use " +"the order they were added to the comic." +msgstr "" +"Ikke sorter filene i tegneserien alfabetisk etter navn. Bruk rekkefølgen " +"filene ble lagt til i tegneserien." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 +msgid "" +"Choose a profile for the device you are generating this LRF for. The default " +"is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" +msgstr "" +"Velg en profil for lagringsenheten denne LRF filen blir generert for. " +"Standard er SONY PRS-500 med skjermstørrelse på 584x754. Valgmulighetene er " +"%s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 +msgid "" +"Be verbose, useful for debugging. Can be specified multiple times for " +"greater verbosity." +msgstr "" +"Informativ modus, nyttig for feilretting. Kan bli spesifisert flere ganger " +"for å motta ytterligere informasjon." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 +msgid "Don't show progress bar." +msgstr "Ikke vis fremskrittssøyle." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 +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:378 +msgid "Output written to" +msgstr "Utdata blir skrevet til" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Prosesserer tegneserie sider..." + +#: /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 "" +"Bruksmåte: %prog [opsjoner] minbok.epub\n" +" \n" +" \n" +"%prog konverterer minbok.epub til minbok.lrf" + +#: /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 "" +"Bruk: %prog [opsjoner] minbok.epub\n" +" \n" +" \n" +"%prog konverterer minbok.epub til minbok.lrf" + +#: /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 "Skriv ut generert HTML til stdout og avslutt." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 +msgid "Keep generated HTML files after completing conversion to LRF." +msgstr "" +"Behold generert HTML filer etter å ha fullført konverteringen til LRF." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 +msgid "Options to control the behavior of feeds2disk" +msgstr "Opsjoner for å kontrollere oppførselen til feeds2disk" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +msgid "Options to control the behavior of html2lrf" +msgstr "Opsjoner for å kontrollere oppførselen til html2lrf" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 +msgid "Fetching of recipe failed: " +msgstr "Innehenting av oppskrift feilet: " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316 +msgid "\tBook Designer file detected." +msgstr "\tBook Designer fil oppdaget." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 +msgid "\tParsing HTML..." +msgstr "\tProsesserer HTML..." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 +msgid "\tBaen file detected. Re-parsing..." +msgstr "\tBaen fil oppdaget. Analyserer på nytt..." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 +msgid "Written preprocessed HTML to " +msgstr "Skrevet førbehandlet HTML til " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 +msgid "Processing %s" +msgstr "Behandler %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 +msgid "\tConverting to BBeB..." +msgstr "\tKonverterer til 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 +msgid "Could not parse file: %s" +msgstr "Kunne ikke analysere fil: %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:537 +msgid "%s is an empty file" +msgstr "%s er en innholdsløs fil" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 +msgid "Failed to parse link %s %s" +msgstr "Analysering av lenken feilet %s %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 +msgid "Cannot add link %s to TOC" +msgstr "Kan ikke legge til lenken %s i innholdsregisteret" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 +msgid "Unable to process image %s. Error: %s" +msgstr "Kunne ikke behandle bilde %s. Feilmelding: %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 +msgid "Unable to process interlaced PNG %s" +msgstr "Behandlingen av linjeflettet PNG feilet %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 +msgid "" +"Could not process image: %s\n" +"%s" +msgstr "" +"Behandlingen av bildet feilet: %s\n" +"%s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 +msgid "" +"An error occurred while processing a table: %s. Ignoring table markup." +msgstr "" +"Under behandlingen av en tabell inntraff det en feil: %s. Ignorer tabell " +"markup." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 +msgid "" +"Bad table:\n" +"%s" +msgstr "" +"Dårlig tabell:\n" +"%s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 +msgid "Table has cell that is too large" +msgstr "Tabellen har en celle som er for stor" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 +msgid "" +"You have to save the website %s as an html file first and then run html2lrf " +"on it." +msgstr "Nettstedet %s må lagres som en html fil før man kjører html2lrf." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 +msgid "Could not read cover image: %s" +msgstr "Kunne ikke lese omslagsbilde: %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 +msgid "Cannot read from: %s" +msgstr "Kan ikke lese fra: %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +msgid "Failed to process opf file" +msgstr "Behandlingen av opf filen feilet" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 +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 "" +"Bruksmåte: %prog [opsjner] minbok.html\n" +"\n" +"\n" +"%prog konverterer minbok.html til minbok.lrf. \n" +"%prog følger alle lenker rekursivt i minbok.html som peker til lokale filer. " +"På denne måten kan du konvertere et helt filtre av HTML filer." + +#: /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 "" +"Bruksmåte: %prog [opsjoner] minbok.lit\n" +"\n" +"\n" +"%prog konverterer minbok.lit til minbok.lrf" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +msgid "" +"%prog book.lrf\n" +"Convert an LRF file into an LRS (XML UTF-8 encoded) file" +msgstr "" +"%prog bok.lrf\n" +"Konverterer en LRF fil til en LRS (XML UTF-8 tegnkodet) fil" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 +msgid "Output LRS file" +msgstr "Skriv ut LRS fil" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 +msgid "Parsing LRF..." +msgstr "Analyserer LRF..." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 +msgid "Creating XML..." +msgstr "Oppretter XML..." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 +msgid "LRS written to " +msgstr "LRS skrevet til " + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 +msgid "Could not read from thumbnail file:" +msgstr "Kunne ikke lese fra thumbnail fil:" + +#: /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 [opsjoner] fil.lrs\n" +"Kompilerer en LRS fil til en LRS fil." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 +msgid "Path to output file" +msgstr "Filsti til utfil" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 +msgid "Verbose processing" +msgstr "Informativ behandling" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 +msgid "Convert LRS to LRS, useful for debugging." +msgstr "Konverter LRS til LRS, praktisk for feilsøking." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:455 +msgid "Invalid LRF file. Could not set metadata." +msgstr "Ugyldig LRF fil. Kunne ikke angi metadata." + +#: /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 "" +"%prog [opsjoner] minbok.lrf\n" +"\n" +"\n" +"Vis/endre metadataene i en LRF fil.\n" +"\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 +msgid "Set the book title" +msgstr "Angi bok tittel" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:589 +msgid "Set sort key for the title" +msgstr "Angi sorteringsnøkkel for tittelen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:591 +msgid "Set the author" +msgstr "Angi forfatter" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:593 +msgid "Set sort key for the author" +msgstr "Angi sorteringsnøkkel for forfatter" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 +msgid "The category this book belongs to. E.g.: History" +msgstr "Boksjanger. For eksempel: Historie" + +#: /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 "Filsti til et bilde som vil bli brukt som denne filens thumbnail" + +#: /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 "" +"Filsti til en tekstfil som inneholder kommentarer som skal lagres i lrf " +"filen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:605 +msgid "Extract thumbnail from LRF file" +msgstr "Hent ut thumbnail fra LRF filen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 +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 "" +"Hent omslagsbilde fra LRF filen. Hvis LRF formatet ikke har definert et " +"omslagsbilde, vil det bli foretatt et søk for å gjette omslagsbildet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:609 +msgid "Set book ID" +msgstr "Angi bok ID" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 +msgid "Don't know what this is for" +msgstr "Vet ikke hva funksjonen til denne er" + +#: /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 "" +"Bruksbeskrivelse: %prog [opsjoner] minbok.mobi|prc\n" +"\n" +"\n" +"%prog konverterer minbok.mobi til minbok.lrf" + +#: /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 "" +"Fant ikke pdftohtml, sjekk om filstien er tilstede i PATH miljøvariabelen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 +msgid " does not allow copying of text." +msgstr " tillater ikke tekst kopiering." + +#: /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:24 +msgid "Set the authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 +msgid "Set the comment" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 +msgid "A comma separated list of tags to set" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 +msgid "Usage:" +msgstr "Bruksmåte:" + +#: /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:37 +#: /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:96 +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:107 +msgid "The ISBN ID of the book you want metadata for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 +msgid "The author whose book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 +msgid "The title of the book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +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:40 +msgid "Usage: %s file.lit" +msgstr "Bruksmåte: %s fil.lit" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:50 +msgid "Cover saved to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:36 +msgid "Usage: pdf-meta file.pdf" +msgstr "Bruksmåte: pdf-meta fil.pdf" + +#: /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/reader.py:421 +msgid "%prog [options] myebook.mobi" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 +msgid "Raw MOBI HTML saved in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 +msgid "Title" +msgstr "" + +#: /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:356 +#: /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:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 +msgid "Comments" +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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/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/password_ui.py:56 +#: /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:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +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:23 +msgid "Basic" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:24 +msgid "Advanced" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 +msgid "Invalid database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 +msgid "Invalid database location.<br>Cannot write to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting database. This may take a while." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +msgid "Configuration" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:236 +msgid "Browse for the new database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 +#: /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:226 +#: /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:229 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +msgid "..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +msgid "Use &Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 +msgid "&Number of covers to show in browse mode (after restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +msgid "Show notification when &new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 +msgid "Ask for &confirmation before deleting files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +msgid "Format for &single file save:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 +msgid "&Priority for conversion jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +msgid "Default network &timeout:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +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:246 +msgid " seconds" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 +msgid "Toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 +msgid "Large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 +msgid "Medium" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 +msgid "Small" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 +msgid "&Button size in toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 +msgid "Show &text in toolbar buttons" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 +msgid "Select visible &columns in library view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 +msgid "Add a directory to the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 +msgid "Remove a directory from the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 +msgid "Free unused diskspace from the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 +msgid "&Compact database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 +msgid "&Metadata from file name" +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:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 +msgid "Author(s)" +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:31 +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:97 +msgid "Choose the format to convert into LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:105 +msgid "Convert %s to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 +msgid "Set conversion defaults" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 +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:256 +msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:257 +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:258 +msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +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:292 +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:293 +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:303 +msgid "<font color=\"gray\">No help available</font>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:404 +msgid "Bulk convert ebooks to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +msgid "Convert to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +msgid "Category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +msgid "Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid "Base &font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +msgid " pts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 +msgid "Embedded Fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +msgid "&Serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 +msgid "S&ans-serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 +msgid "&Monospace:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +msgid "Minimum &indent:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +msgid "&Word spacing:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +msgid "Enable auto &rotation of images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +msgid "Insert &blank lines between paragraphs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "Ignore &tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +msgid "Ignore &colors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Preprocess:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +msgid "Header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Show header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +msgid "&Header format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "Override<br>CSS" +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:552 +#: /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:556 +msgid " px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +msgid "&Convert tables to images (good for large/complex tables)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +msgid "&Multiplier for text size in rendered tables:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +msgid "Title based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 +msgid "&Disable chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 +msgid "&Regular expression:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 +msgid "Add &chapters to table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +msgid "Don't add &links to the table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 +msgid "Tag based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +msgid "&Page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 +msgid "&Force page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 +msgid "Force page break before &attribute:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 +msgid "Detect chapter &at tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 +msgid "Help on item" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 +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; font-" +"family:'Sans Serif'; font-size:9pt;\"></p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:114 +msgid "Edit Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +msgid "Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 +msgid "Author S&ort: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 +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:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +msgid "&Rating:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 +msgid "Rating of this book. 0-5 stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +msgid " stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 +msgid "Add Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +msgid "Open Tag Editor" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 +msgid "&Remove tags:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 +msgid "Comma separated list of tags to remove from the books. " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 +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:284 +msgid "<b>Could not fetch cover.</b><br/>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 +msgid "Could not fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "Cannot fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "You must specify the ISBN identifier for this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +msgid "Edit Meta Information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 +msgid "Swap the author and title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 +msgid "Fetch metadata from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 +msgid "Available Formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 +msgid "Add a new format for this book to the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +msgid "Remove the selected formats for this book from the database." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +msgid "Fetch cover image from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +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:317 +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/password_ui.py:57 +msgid "&Username:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 +msgid "&Password:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 +msgid "&Show password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:15 +msgid "Author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:17 +msgid "Tag" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Series" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 +msgid "Format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:21 +msgid "Any" +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:73 +msgid "Advanced Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:74 +msgid "Match a&ll of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:75 +msgid "Match a&ny of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:76 +msgid "Search criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:77 +msgid "More" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:78 +msgid "Fewer" +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:63 +msgid "No recipe selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 +msgid "The attached file: %s is a recipe to download %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 +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:214 +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 +msgid "Switch to Basic mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 +msgid "Feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:111 +msgid "The feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 +msgid "Feed must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:116 +msgid "The feed %s must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 +msgid "Already exists" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:122 +msgid "This feed has already been added to the recipe" +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:195 +msgid "Invalid input" +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:196 +msgid "<p>Could not create recipe. Error:<br>%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 +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:202 +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:188 +msgid "Choose a recipe file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:188 +msgid "Recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:208 +msgid "Add custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:209 +msgid "Available user recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:210 +msgid "Add/Update &recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:211 +msgid "&Remove recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:212 +msgid "&Share recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:213 +msgid "&Load recipe from file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 +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:219 +msgid "Recipe &title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:220 +msgid "&Oldest article:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:221 +msgid "The oldest article to download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:222 +msgid " days" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:223 +msgid "&Max. number of articles per feed:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:224 +msgid "Maximum number of articles to download per feed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:225 +msgid "Feeds in recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:227 +msgid "Remove feed from recipe" +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:233 +msgid "Add feed to recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:231 +msgid "&Feed title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:232 +msgid "Feed &URL:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:234 +msgid "&Add feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:235 +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:236 +msgid "Recipe source code (python)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 +msgid "" +"<p>Set a regular expression pattern to use when trying to guess ebook " +"metadata from filenames. <p>A <a href=\"http://docs.python.org/lib/re-" +"syntax.html\">reference</a> on the syntax of regular expressions is " +"available.<p>Use the <b>Test</b> functionality below to test your regular " +"expression on a few sample filenames." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:98 +msgid "Regular &expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:99 +msgid "&Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:100 +msgid "File &name:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:101 +msgid "Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:102 +msgid "Title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:103 +msgid "Regular expression group name (?P<title>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:107 +#: /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/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:105 +msgid "Authors:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 +msgid "Regular expression group name (?P<authors>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 +msgid "Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 +msgid "Regular expression group name (?P<series>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 +msgid "Series index:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 +msgid "Regular expression group name (?P<series_index>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 +msgid "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:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 +msgid "Cannot kill job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 +msgid "None" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +msgid "Book <font face=\"serif\">%s</font> of %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 +msgid "Double click to <b>edit</b> me<br><br>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 +msgid "Size (MB)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 +msgid "Date" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 +msgid "Rating" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 +msgid "Timestamp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 +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 +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 +msgid "Back" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:134 +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 +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:85 +msgid "Error communicating with device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 +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:99 +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:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +msgid "Send to main memory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "Send to storage card" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "and delete from library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 +msgid "Send to storage card by default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +msgid "Edit metadata individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +msgid "Edit metadata in bulk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 +msgid "Add books from a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 +msgid "" +"Add books recursively (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:141 +msgid "" +"Add books recursively (Multiple books per directory, assumes every ebook " +"file is a different book)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 +msgid "Save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 +msgid "Save to disk in a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +msgid "Save only %s format to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 +msgid "View" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 +msgid "View specific format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +msgid "Convert individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +msgid "Bulk convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 +msgid "Set defaults for conversion of comics" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 +msgid "Device: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 +msgid "Connected " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 +msgid "Device database corrupted" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 +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:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 +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:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 +msgid "Duplicates found!" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 +msgid "Uploading books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 +msgid "No space on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 +msgid "" +"<p>Cannot upload books to device there is no more free space available " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 +msgid "Confirm delete" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 +msgid "Are you sure you want to delete these %d books?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 +msgid "Deleting books from device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +msgid "Cannot edit metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "No books selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 +msgid "Sending books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 +msgid "No suitable formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 +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:758 +msgid "Cannot save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 +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:773 +msgid "Could not save some ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 +msgid "Fetching news from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 +msgid "News fetched. Uploading to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +msgid "No book selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 +msgid "Cannot view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 +msgid "Choose the format to view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 +msgid "%s has no available formats." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure while there are running jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +msgid "Invalid database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 +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:1041 +msgid "Could not move database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 +msgid "No detailed info available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 +msgid "No detailed information is available for books on the device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 +msgid "Error talking to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 +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:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 +msgid "Conversion Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 +msgid "Database does not exist" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 +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:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 +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:1216 +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:1216 +msgid "Update available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +msgid "calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +msgid "Advanced search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +msgid "Alt+S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +msgid "&Search:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +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:277 +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:278 +msgid "Reset Quick Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 +msgid "Add books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 +msgid "A" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 +msgid "Remove books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 +msgid "Del" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 +msgid "Edit meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 +msgid "E" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 +msgid "Send to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 +msgid "S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 +msgid "Fetch news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 +msgid "F" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 +msgid "Convert E-books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 +msgid "C" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 +msgid "V" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:17 +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 +msgid "ERROR: Unhandled exception" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:32 +msgid "Add a custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 +msgid "" +"<p>Please enter your username and password for %s<br>If you do not have one, " +"please subscribe to get access to the articles.<br/> Click OK to proceed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 +msgid "Custom news sources" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +msgid "Jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 +msgid "Click to see list of active jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to browse books by their covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to turn off Cover Browsing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 +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:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:178 +msgid "Library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 +msgid "" +"Reader\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 +msgid "" +"Card\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 +msgid "Click to see the list of books available on your computer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 +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:186 +msgid "Click to see the list of books on the storage card in your reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 +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:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 +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:94 +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" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +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:98 +msgid "Sort results in ascending order" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 +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:106 +msgid "Invalid fields. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 +msgid "Invalid sort field. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 +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:201 +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:210 +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:212 +msgid "Process directories recursively" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 +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:219 +msgid "You must specify at least one file to add" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 +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:249 +msgid "You must specify at least one book to remove" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 +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:280 +msgid "You must specify an id and an ebook file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 +msgid "ebook file must have an extension" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 +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:306 +msgid "You must specify an id and a format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 +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:332 +msgid "Print metadata in OPF form (XML)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 +msgid "You must specify an id" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 +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:364 +msgid "You must specify an id and a metadata file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 +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:384 +msgid "Export all books in database, ignoring the list of ids." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 +msgid "Export books to the specified directory. Default is" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 +msgid "Export all books into a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 +msgid "Create file names as author - title instead of title - author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 +msgid "You must specify some ids or the %s option" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 +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:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 +msgid "Could not launch worker process." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sBruksområde%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Utviklet av " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 +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:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77 +msgid "Unknown feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:95 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:117 +msgid "Untitled article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 +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:86 +msgid "" +"Options to control web2disk (used to fetch websites linked from feeds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 +msgid "Dont show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 +msgid "Fetching feeds..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 +msgid "Unknown News Source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 +msgid "Download finished" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 +msgid "Failed to download the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 +msgid " from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 +msgid "Failed to download parts of the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 +msgid "\tFailed links:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 +msgid "Could not fetch article. Run with --debug to see the reason" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 +msgid "Got feeds from index page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 +msgid "Trying to download cover..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +msgid "Starting download [%d thread(s)]..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 +msgid "Feeds downloaded to %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 +msgid "Could not download cover: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 +msgid "Downloading cover from %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 +msgid "Untitled Article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 +msgid "" +"\n" +"Downloaded article %s from %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 +msgid "Article downloaded: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 +msgid "Failed to download article: %s from %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 +msgid "Article download failed: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 +msgid "Fetching feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 +msgid "" +"%prog URL\n" +"\n" +"Where URL is for example http://google.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 +msgid "Base directory into which URL is saved. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +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:408 +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:419 +msgid "Show detailed output information. Useful for debugging" +msgstr "" diff --git a/src/calibre/translations/nds.po b/src/calibre/translations/nds.po index 9e00792b71..bda8ab4ad0 100644 --- a/src/calibre/translations/nds.po +++ b/src/calibre/translations/nds.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-08-04 13:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-29 13:13+0000\n" "Last-Translator: S. Dorscht <Unknown>\n" "Language-Team: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" @@ -55,9 +55,22 @@ msgstr "" #~ msgid "The author whoose book to search for." #~ msgstr "Der Autor des gesuchten Buches." +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "Speicherort der Bücherdatenbank (&library1.db)" + #~ msgid "&Access Key;" #~ msgstr "&Zugriffsschlüssel:" +#~ msgid "" +#~ "Cannot kill jobs that are communicating with the device as this may cause " +#~ "data corruption." +#~ msgstr "" +#~ "Kann Aufträge nicht abbrechen, die mit dem Gerät kommunizieren, da dies zu " +#~ "Datenverlust führen kann." + +#~ msgid "Cannot kill already completed jobs." +#~ msgstr "Kann schon fertiggestellte Aufträge nicht abbrechen." + #~ msgid "Cannot kill waiting jobs." #~ msgstr "Kann Aufträge in Warteliste nicht abbrechen." @@ -74,14 +87,78 @@ msgstr "" #~ "Speichern Sie den unten stehenden Text als Rezept.py Datei und senden Sie " #~ "die Datei an Freunde, damit sie dieses Rezept ebenfalls benutzen können." +#~ msgid "Copying database to " +#~ msgstr "Kopiere Datenbank nach " + +#~ msgid "" +#~ "Path to the calibre database. Default is to use the path stored in the " +#~ "settings." +#~ msgstr "" +#~ "Pfad zur Datenbank von calibre. Die Voreinstellung ist der in den " +#~ "Einstellungen gespeicherte Pfad." + +#~ msgid "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "List the books available in the calibre database. \n" +#~ msgstr "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "Listet die in der Datenbank von calibre verfügbaren Bücher auf. \n" + +#~ 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 "" +#~ "%prog add [options] Datei1 Datei2 Datei3 ...\n" +#~ "\n" +#~ "Fügt die angegebenen Dateien als Bücher zur Datenbank hinzu. Sie können auch " +#~ "Verzeichnisse angeben, sehen Sie sich dazu die zu den Verzeichnissen " +#~ "gehörigen Optionen weiter unten an. \n" + +#~ 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 "" +#~ "%%prog command [options] [arguments]\n" +#~ "\n" +#~ "%%prog ist die Befehlszeilenschnittstelle zur Bücher Datenbank von calibre. " +#~ "\n" +#~ "\n" +#~ "command ist eines der folgenden:\n" +#~ " %s\n" +#~ " \n" +#~ "Für Hilfe zu einem bestimmten Befehl (command): %%prog command --help\n" + +#~ 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\". Default is %default" +#~ msgstr "" +#~ "Erkenne einen Kapitelanfang anhand des Elements mit dem angegebenen " +#~ "Attribut. Das Format dieser Option ist tagname regexp,attribute " +#~ "name,attribute value regexp. Um zum Beispiel alle \"header\" (\"h\") " +#~ "Elemente mit dem Attribut class=\"chapter\" anzugleich, müsste man \"h\\" +#~ "d,class,chapter\" benutzen. Voreinstellung ist %default" + #~ 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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -91,53 +168,540 @@ msgstr "" #~ "<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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sBenutzung%s: %s\n" +#~ 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 "" +#~ "\n" +#~ "%prog show_metadata [options] id\n" +#~ "\n" +#~ "Zeige die in der calibre Datenbank gespeicherten Meta-Daten für das durch " +#~ "die ID erkannte Buch. \n" +#~ "\"id\" ist eine ID Nummer des Befehls \"list\". \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Erstellt von " +#~ 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 "" +#~ "\n" +#~ "%prog set_metadata [options] id /verzeichnis/zu/metadata.opf\n" +#~ "\n" +#~ "Übernehme die Meta-Daten, die in der calibre Datenbank für das durch die ID " +#~ "erkannte Buch gespeichert werden,\n" +#~ "aus der OPF Datei metadata.opf. \"id\" ist eine ID Nummer des Befehls " +#~ "\"list\". Sie erhalten \n" +#~ "einen Eindruck über das OPF Format, wenn Sie die --as-opf Option mit dem \n" +#~ "Befehl show_metadata verwenden.\n" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ 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 "" +#~ "%prog export [options] ids \n" +#~ "\n" +#~ "Exportiert die durch IDs angegebenen Bücher (als durch Kommata getrennte " +#~ "Liste) in das Dateisystem.\n" +#~ "Der Export speichert alle Formate des Buches, sein Umschlagbild und die Meta-" +#~ "Daten (in \n" +#~ "einer OPF Datei). Sie erhalten ID Nummern mit dem Befehl \"list\". \n" + +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Konvertiert ein Comic einer CBZ oder CBR Datei in ein LRF eBook. \n" + +#~ msgid "Set defaults for conversion to LRF" +#~ msgstr "Voreinstellungen für die Konvertierung zu LRF Dateien setzen" + +#~ msgid "Convert comic %d of %d (%s)" +#~ msgstr "Konvertiere Comic %d von %d (%s)" + +#~ msgid "" +#~ "An XPath expression to detect chapter titles. The default is to consider " +#~ "<h1> or\n" +#~ "<h2> tags that contain the text \"chapter\" or \"book\" or \"section\" as " +#~ "chapter titles. \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 "" +#~ "Ein XPath Ausdruck zur Erkennung von Kapitelüberschriften. In der " +#~ "Voreinstellung werden <h1> oder <h2> Tags, \n" +#~ "die den Text \"chapter\" oder \"book\" oder \"section\" enthalten, als " +#~ "Kapitelüberschriften betrachtet. \n" +#~ "Der verwendete Ausdruck muss durch eine Liste von Elementen festgelegt sein. " +#~ "Zum Ausschalten der Kapitelerkennung \n" +#~ "verwenden Sie den Ausdruck \"/\". Weitere Hilfe zur Benutzung dieser " +#~ "Funktion finden Sie im XPath Tutorial des calibre \n" +#~ "User Manual.\n" + +#~ msgid "Don't add detected chapters to the Table of Contents" +#~ msgstr "Erkannte Kapitel nicht ins Inhaltsverzeichnis übernehmen" + +#~ msgid "Don't add links in the root HTML file to the Table of Contents" +#~ msgstr "" +#~ "Verknüpfungen aus der ursprünglichen HTML Datei nicht ins Inhaltsverzeichnis " +#~ "übernehmen" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Convert a HTML file to an EPUB ebook. Follows links in the HTML file. \n" +#~ msgstr "" +#~ "%prog [options] datei.html\n" +#~ "\n" +#~ "Konvertiert eine HTML Datei in ein EPUB eBook. Verfolgt Verknüpfungen in der " +#~ "HTML Datei. \n" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Follow all links in an HTML file and collect them into the specified " +#~ "directory.\n" +#~ "Also collects any references resources like images, stylesheets, scripts, " +#~ "etc. \n" +#~ msgstr "" +#~ "%prog [options] datei.html\n" +#~ "\n" +#~ "Verfolgt alle Verknüpfungen in einer HTML Datei und sammelt sie in dem " +#~ "angegebenen Verzeichnis.\n" +#~ "Sammelt zudem jegliche Hinweise und Quellen wie Bilder, Stylesheets, " +#~ "Skripte, etc. \n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "Konnte das Laufwerk %s nicht finden. Versuchen Sie einen Neustart." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "Im Reader ist keine Speicherkarte eingesteckt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Einstellungen zur Kontrolle der Konvertierung zu EPUB Dateien" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"EPUB Ausgabedatei. Falls nicht angegeben, wird es vom ursprünglichen " +"Dateinamen abgeleitet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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 "" +"Profil des Zielgeräts für das diese EPUB Datei gedacht ist. Die Einstellung " +"\"Kein\" erstellt eine geräteunabhängige EPUB Datei. Das Profil wird für " +"gerätespezifische Einschränkungen der EPUB Datei verwendet. Es gibt folgende " +"Wahlmöglichkeiten: " + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:63 +msgid "" +"Either the path to a CSS stylesheet or raw CSS. This CSS will override any " +"existing CSS declarations in the source files." +msgstr "" +"Entweder der Pfad zu einem CSS Stylesheet oder original CSS. Dieses CSS " +"überschreibt alle existierenden CSS Angaben in den Ursprungsdateien." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:64 +msgid "Control auto-detection of document structure." +msgstr "Kontrolle der automatischen Erkennung der Dokumentstruktur." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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 "" +"Ein XPath Ausdruck zur Erkennung von Kapitelüberschriften. In der " +"Voreinstellung werden <h1> oder\n" +"<h2> Tags verwendet, die die Worte \"chapter\",\"book\",\"section\" oder " +"\"part\" als Kapitelüberschriften\n" +"enthalten und genauso alle Tags, die class=\"chapter\" enthalten. \n" +"Der verwendete Ausdruck muss eine Liste von Elementen auswerten. Die " +"Kapitelerkennung wird durch die\n" +"Verwendung des Ausdrucks \"/\" ausgeschaltet. Ein Hilfe zur Verwendung " +"dieses Features gibt es im\n" +"XPath Tutorial im calibre User Manual.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:75 +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 "" +"Geben Sie an, wie erkannte Kapitel gekennzeichnet werden sollen. Der Wert " +"\"pagebreak\" fügt Seitenumbrüche vor Kapiteln ein. Der Wert \"rule\" fügt " +"eine Linie vor Kapiteln ein. Der Wert \"none\" schaltet die " +"Kapitelmarkierung aus und der Wert \"both\" verwendet sowohl Seitenumbrüche " +"als auch Linien zur Kapitelmarkierung." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:77 +msgid "Path to the cover to be used for this book" +msgstr "Pfad zum Umschlagbild, das für dieses Buch verwendet werden soll" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +msgid "" +"Use the cover detected from the source file in preference to the specified " +"cover." +msgstr "" +"Verwendet bevorzugt das aus der Ursprungsdatei gewonnene Umschlagbild " +"anstatt des angegebenen Umschlagbildes." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:83 +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 "" +"Kontrolle der automatischen Erstellung eines Inhaltsverzeichnisses. Falls " +"eine OPF Datei erkannt\n" +"wird und sie ein Inhaltsverzeichnis angibt, wird dieses verwendet anstatt zu " +"versuchen\n" +"ein Inhaltsverzeichnis automatisch zu erstellen.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:89 +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 "" +"Höchstzahl der Verknüpfungen, die in das Inhaltsverzeichnis eingefügt " +"werden. Zum Ausschalten auf 0 setzen. Voreinstellung ist: %default. " +"Verknüpfungen werden nur dann zum Inhaltsverzeichnis hinzugefügt, wenn " +"weniger Kapitel als in --toc-threshold angegeben erkannt werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "Automatisch erkannte Kapitel nicht zum Inhaltsverzeichnis hinzufügen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" +"Falls weniger Kapitel erkannt werden als in dieser Zahl angegeben, dann " +"werden Verknüpfungen zum Inhaltsverzeichnis hinzugefügt." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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 "" +"Normalerweise wird, falls die Ursprungsdatei schon ein Inhaltsverzeichnis " +"enthält, dieses anstelle des automatisch erkannten verwendet. Mit dieser " +"Option wird immer das automatisch erkannte Inhaltsverzeichnis verwendet." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:97 +msgid "Control page layout" +msgstr "Einstellungen des Seitenlayouts" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" +"Oberen Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" +"Unteren Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" +"Linken Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" +"Rechten Rand der Seite in Punkt eingeben. Die Voreinstellung ist %default" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "Erstellte OPF Datei nach stdout ausgeben" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "Erstellte NCX Datei nach stdout ausgeben" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "Zwischendateien während des Verarbeitens mit html2epub beibehalten" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +msgid "" +"Extract the contents of the produced EPUB file to the specified directory." +msgstr "" +"Den Inhalt der erstellten EPUB Datei in das angegebene Verzeichnis " +"extrahieren." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Unbekannt" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "Konnte kein eBook im Archiv finden" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" +"%%prog [options] Dateiname\n" +"\n" +"Konvertiert eine große Anzahl von eBook Formaten in eine EPUB Datei. " +"Unterstützte Formate: %s\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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 "" +"%prog [options] file.html|opf\n" +"\n" +"Konvertiert eine HTML Datei in ein EPUB eBook. Verfolgt Verknüpfungen in der " +"HTML Datei rekursiv.\n" +"Falls statt der HTML Datei eine OPF Datei angegeben wird, wird die Liste der " +"Verknüpfungen aus dem\n" +"<spine> Element der OPF Datei verwendet. \n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "Geben Sie eine Eingabedatei im HTML Format an." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +msgid "" +"Could not find reasonable point at which to split: %s Sub-tree size: %d KB" +msgstr "" +"Konnte keinen vernünftige Stelle zur Trennung finden: %s Unterbaumgröße: %d " +"KB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:85 +msgid "" +"\t\tToo much markup. Re-splitting without structure preservation. This may " +"cause incorrect rendering." +msgstr "" +"\t\tZu viel Textauszeichnung. Wieder-Aufteilung ohne Bewahrung der Struktur. " +"Dies kann zu falschem Rendering führen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:390 +msgid "Written processed HTML to " +msgstr "Verarbeitetes HTML wurde geschrieben in " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "Einstellungen zur Kontrolle der Durchforstung von HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "Ausgabeverzeichnis. Voreinstellung ist das aktuelle Verzeichnis." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" +"Zeichenkodierung für HTML Dateien. Die Voreinstellung ist automatisches " +"Erkennen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Erstellt die Ausgabe in eine ZIP Datei. Wird diese Option angegeben, sollte -" +"-output der Name einer Datei und nicht eines Verzeichnisses sein." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Kontrolliert die Verfolgung von Verknüpfungen in HTML Dateien." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" +"Durchforstet Verknüpfungen in HTML Dateien zuerst in die Breite. " +"Normalerweise werden sie zuerst in die Tiefe durchforstet" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Maximale Höhe der Rekursion bei der Verfolgung von Verknüpfungen in HTML " +"Dateien. Darf nicht negativ sein. 0 gibt an, dass keine Verknüpfungen in der " +"ursprünglichen HTML Datei verfolgt werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Geben Sie die Metadaten des erstellten eBooks an" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Geben Sie den Titel an. Voreinstellung ist automatische Ermittlung." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "Autor(en) des eBooks, als durch Kommata getrennte Liste." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "Metadaten aus der angegebenen OPF Datei laden" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Hilfreiche Einstellungen zur Fehlersuche" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" +"Noch ausführlicher bei der weiteren Verarbeitung vorgehen. Kann zur " +"Vergrößerung der Ausführlichkeit mehrfach angegeben werden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" +"Ausgabe HTML ist \"hübsch gedruckt\" zur einfacheren Analyse durch " +"menschliche Wesen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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 "" +"%prog [options] file.html|opf\n" +"\n" +"Folgt allen Verknüpfungen in einer HTML Datei und sammelt sie in das " +"angegebene Verzeichnis.\n" +"Sammelt zudem jegliche verwiesene Quellen wie Bilder, Stylesheets, Skripte, " +"usw.\n" +"Falls stattdessen eine OPF Datei angegeben wird, wird die Liste der Dateien " +"in ihrem <spine> Element\n" +"verwendet.\n" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:813 msgid "%prog [options] LITFILE" msgstr "%prog [options] LITFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "Ausgabeverzeichnis. Voreinstellung ist akutelles Verzeichnis." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" +"Lesbares Format der extrahierten Textauszeichnung. Könnte sinnvolle " +"Freiräume abändern." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Hilfreich bei der Fehlersuche." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "OEB eBook erstellt in" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Geben Sie den Titel an. Voreinstellung: Dateiname." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -145,49 +709,34 @@ msgstr "" "Geben Sie den Autor an. Mehrere Autoren sollten durch Kommata getrennt " "angegeben werden. Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Unbekannt" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Geben Sie eine Bemerkung an." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Geben Sie eine Kategorie an." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Sortierung nach Titel" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Sortierung nach Autor" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Herausgeber" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Pfad zur Datei des Umschlagbildes" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -195,13 +744,13 @@ msgstr "" "Falls die Quelldatei ein Umschlagbild enthält, das Umschlagbild der " "Quelldatei benutzen, anstatt des angegebenen Umschlagbildes." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" "Ausgabedateiname. Die Voreinstellung leitet sich vom ursprünglichen " "Dateinamen ab." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -209,7 +758,7 @@ msgstr "" "HTML Tabellen als Textblöcke rendern und nicht als Tabellen. Dies ist " "notwendig, wenn die HTML Datei sehr große oder komplexe Tabellen enthält." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -220,27 +769,27 @@ msgstr "" "Option außer Gebrauch und wird bevorzugt behandelt. Um --font-delta zu " "benutzen, geben Sie 0 an. Voreinstellung: %defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Automatische Rotation von Bildern, die breiter als die Bildschirmbreite " "sind, einschalten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" "Wählen Sie den Abstand in Punkt zwischen einzelnen Wörtern. Die " "Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Paragraphen durch Leerzeilen trennen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Kopfzeile mit Titel und Autor für alle Seiten einfügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -248,7 +797,7 @@ msgstr "" "Wählen Sie das Format der Kopfzeile. %a wird durch den Autor und %t durch " "den Titel ersetzt. Die Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -256,7 +805,7 @@ msgstr "" "CSS überschreiben. Es kann ein Pfad zu einem CSS Stylesheet oder eine " "Zeichenfolge angegeben werden. Zeichenfolgen werden als CSS interpretiert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -266,7 +815,7 @@ msgstr "" "in der die HTML Dateien zur LRF Datei hinzugefügt werden. Die OPF Datei muss " "sich im gleichen Verzeichnis wie die ursprüngliche HTML Datei befinden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -274,7 +823,7 @@ msgstr "" "Mindest-Zeileneinzug von Paragraphen (Zeileneinzug der ersten Zeile eines " "Paragraphen) in Punkt. Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -284,14 +833,14 @@ msgstr "" "vergrößern. FONT_DELTA kann ein Bruchteil sein. Falls FONT_DELTA negativ " "angegeben wird, wird die Schriftgröße verkleinert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." msgstr "" "Inhalt schwarz-weiß rendern anstatt in den in HTML oder CSS angegeben Farben." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -301,23 +850,23 @@ msgstr "" "unter anderem die Auflösung und die Bildschirmgröße des Zielgerätes fest. " "Voreinstellung: %s Unterstützte Profile: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Linker Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Rechter Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Oberer Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Unterer Rand der Seite. Die Voreinstellung ist %default Pixel." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -325,7 +874,7 @@ msgstr "" "Tabellen in HTML als Bilder rendern (hilfreich, wenn das Dokument große oder " "komplexe Tabellen enthält)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -333,7 +882,7 @@ msgstr "" "Textgröße in gerenderten Tabellen um diesen Faktor erhöhen. Voreinstellung " "ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -343,7 +892,7 @@ msgstr "" "dass Verknüpfungen ignoriert werden. Ein negativer Wert bedeutet, dass alle " "<a> Elemente ignoriert werden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -351,15 +900,15 @@ msgstr "" "Ein regulärer Ausdruck. <a> Elemente, deren Verknüpfungen ignoriert werden. " "Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Keine Links zum Inhaltsverzeichnis hinzufügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Automatische Erkennung von Kapiteln verhindern." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -367,20 +916,24 @@ msgstr "" "Der reguläre Ausdruck zur Ermittlung von Kapitelüberschriften. Es wird nach " "mit (h1) - (h6) angegebenen Überschriften gesucht. Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" -"Erkenne einen Kapitelanfang anhand des Elements mit dem angegebenen " -"Attribut. Das Format dieser Option ist tagname regexp,attribute " -"name,attribute value regexp. Um zum Beispiel alle \"header\" (\"h\") " -"Elemente mit dem Attribut class=\"chapter\" anzugleich, müsste man \"h\\" -"d,class,chapter\" benutzen. Voreinstellung ist %default" +"Erkennt ein Kapitel, das mit einem Element mit dem angegebenen Attribut " +"beginnt. Das Format für diese Option ist tagname regexp,attribute " +"name,attribute value regexp. Um zum Beispiel alle heading tags zu treffen " +"die das Attribut class=\"chapter\" haben, verwenden Sie \"h\\" +"d,class,chapter\". Sie können das Attribut \"none\" setzen um nur die tag " +"names zu treffen. Wenn Sie zum Beispiel alle <h2> tags treffen wollen, " +"benutzen Sie \"h2,none,\". Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -399,14 +952,14 @@ msgstr "" "Umblättern der in der LRF Datei verlangsamt. Diese Einstellung wird " "ignoriert, wenn die aktuelle Seite nur wenige Elemente enthält." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Seitenumbruch erzwingen vor Elementen, deren Namen diesem regulären Ausdruck " "entsprechen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -419,16 +972,16 @@ msgstr "" "class=\"chapter\" anzupassen, verwenden Sie \"h\\d,class,chapter\". " "Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Die ermittelten Kapitel zum Inhaltsverzeichnis hinzufügen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" "Baen HTML Dateien vorbearbeiten, um die erstellte LRF Datei zu verbessern." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -436,11 +989,11 @@ msgstr "" "Sie müssen diese Auswahl treffen, wenn sie Dateien, die von pdftohtml " "erstellt wurden, verarbeiten wollen, sonst schlägt die Konvertierung fehl." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Benutzen Sie diese Einstellung bei HTML Dateien von Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -454,27 +1007,27 @@ msgstr "" "angegeben: --serif-family \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "Serife Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "Serifenlose Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "Nichtproportionale Schriftartfamilie einbetten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Bei der weiteren Verarbeitung ausführlicher vorgehen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Zu LRS konvertieren" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -483,7 +1036,7 @@ msgstr "" "Benutzen Sie diese Einstellung, wenn sie an einem Rechner mit geringem " "Hauptspeicher arbeiten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -496,7 +1049,7 @@ msgstr "" "cp-1252. Eine andere gebräuchliche Alternative ist utf-8. In der " "Voreinstellung wird versucht, die Kodierung zu erraten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -515,34 +1068,38 @@ msgstr "" "ZIP Archive, indem es nach einem eBook im Archiv sucht.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Keine Datei zur Konvertierung angegeben." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "%s gerendert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "%s schlug fehl" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "" "Einstellungen zur Kontrolle der Konvertierung von Comic (CBR, CBZ) Dateien " "zu eBooks" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" "Titel für erstelltes eBook. In der Voreinstellung wird der Dateiname benutzt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" "Gibt den Autor in den Metadaten des erstellen eBooks an. Voreinstellung ist " "%default." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." @@ -550,34 +1107,58 @@ msgstr "" "Pfad zur ausgegebenen LRF Datei. Laut Voreinstellung wird die Datei im " "aktuellen Verzeichnis erstellt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -"Anzahl der Farben für die Bildkonvertierung in Graustufen. Voreinstellung: " -"%default" +"Anzahl der Farben für die Konvertierung von Graustufenbildern. " +"Voreinstellung: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" "Deaktivieren der Normalisierung (verbessert den Kontrast) des Farbbereichs " "für Bilder. Voreinstellung: False" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" "Seitenverhältnis des Bildes beibehalten. Voreinstellung ist " "bildschirmfüllende Darstellung." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "Schärfen deaktivieren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "Bilder im Querformat nicht in zwei Bilder im Hochformat aufteilen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Seitenverhältnis beibehalten und Bild so skalieren, dass die Bildschirmhöhe " +"als Bildbreite in der Querformatansicht verwendet wird." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Benutzt für rechts-nach-links Publikationen wie Mangas. Querformatige Seiten " +"werden von rechts nach links in mehrere hochformatige Seiten unterteilt." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" +"Entkörnung einschalten. Reduziert die Körnigkeit. Kann die Bearbeitungszeit " +"stark verlängern." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." @@ -586,7 +1167,7 @@ msgstr "" "sortieren, sondern die Reihenfolge verwenden, in der sie zum Comic " "hinzugefügt wurden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" @@ -595,7 +1176,7 @@ msgstr "" "Die Voreinstellung ist der SONY PRS-500 mit einer Bildschirmgröße von " "584x754 Punkten. Wahlmöglichkeiten sind %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." @@ -603,28 +1184,28 @@ msgstr "" "Ausführlicher, hilfreich zur Fehlersuche. Kann mehrmals angegeben werden um " "eine größere Ausführlichkeit zu erreichen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "Fortschrittsbalken nicht anzeigen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +"Convert a comic in a CBZ or CBR file to an ebook. \n" msgstr "" "%prog [options] comic.cb[z|r]\n" "\n" -"Konvertiert ein Comic einer CBZ oder CBR Datei in ein LRF eBook. \n" +"Konvertiert ein Comic einer CBZ oder CBR Datei in ein eBook. \n" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:328 -msgid "Rendering comic pages..." -msgstr "Rendere Seiten des Comics..." - -#: /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:378 msgid "Output written to" msgstr "Ausgabe gespeichert unter" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Rendere Seiten des Comics..." + #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" "Usage: %prog [options] mybook.epub\n" @@ -637,7 +1218,7 @@ msgstr "" " \n" "%prog konvertiert dateiname.epub in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -649,24 +1230,24 @@ msgstr "" "\n" "%prog konvertiert dateiname.fb2 in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Gebe erstellte HTML auf stdout aus und beende das Programm." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "Erstellte HTML Dateien nach vollzogener LRF Konvertierung behalten." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Einstellungen für feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Einstellungen für html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Abruf des Rezepts misslungen: " @@ -694,32 +1275,32 @@ msgstr "Verarbeite %s" msgid "\tConverting to BBeB..." msgstr "\tKonvertiere in BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Konnte Datei nicht analysieren: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%s ist eine leere Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "Fehlschlag bei der Analysierung von %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "Konnte Link %s nicht zu TOC hinzufügen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Konnte Bild %s nicht verarbeiten. Fehler: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "Konnte verschachteltes PNG %s nicht verarbeiten" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -727,14 +1308,14 @@ msgstr "" "Konnte Bild nicht verarbeiten: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" "Ein Fehler trat während der Bearbeitung einer Tabelle auf: %s. " "Tabellenformat wird ignoriert." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -742,11 +1323,11 @@ msgstr "" "Schlechte Tabelle:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "Tabelle enthält Zelle, die zu groß ist" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -754,19 +1335,19 @@ msgstr "" "Sichern Sie die Website %s zuerst als HTML Datei und benutzen Sie dann " "html2lrf mit der gespeicherten HTML Datei." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "Konnte Umschlagbild nicht lesen: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "Lesen nicht möglich von: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Verarbeitung der OPF Datei schlug fehl" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -784,7 +1365,7 @@ msgstr "" "lokale Dateien verweisen. Somit können Sie es verwenden,\n" "um einen ganzen Verzeichnisbaum von HTML Dateien zu konvertieren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -796,7 +1377,7 @@ msgstr "" "\n" "%prog konvertiert dateiname.lit in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -804,27 +1385,27 @@ msgstr "" "%prog dateiname.lrf\n" "Konvertiert eine LRF Datei in eine LRS (XML UTF-8 kodierte) Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Ausgabe LRS Datei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Analysieren LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Erstelle XML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS gespeichert in " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" msgstr "Thumbnail Datei konnte nicht gelesen werden:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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." @@ -832,16 +1413,16 @@ msgstr "" "%prog [options] datei.lrs\n" "Erstellt eine LRF Datei aus einer LRS Datei." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Pfad zur Zieldatei" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "Ausführlicher fortfahren" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "Konvertierung von LRS zu LRS, hilfreich bei der Fehlersuche." @@ -864,7 +1445,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Geben Sie den Buchtitel an" @@ -881,7 +1462,7 @@ msgid "Set sort key for the author" msgstr "Sortierung nach Autor" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "Die Kategorie dieses Buches ... (Z. B.: Geschichte)" @@ -930,24 +1511,24 @@ msgstr "" "\n" "%prog konvertiert dateiname.mobi in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "" "Konnte pdftohtml nicht finden, überprüfen Sie, ob es in der PATH Variable " "angegeben ist" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " lässt das Kopieren von Text nicht zu." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" " ist ein PDF, das aus Bildern hergestellt wurde. Es wird aber nur die " "Konvertierung von aus Text aufgebauten PDF Dateien unterstützt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -959,7 +1540,7 @@ msgstr "" "\n" "%prog konvertiert dateiname.pdf in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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." @@ -967,15 +1548,15 @@ msgstr "" "Pfad zum Ausgabeverzeichnis, in dem die HTML Datei erstellt werden soll. " "Voreinstellung auf aktuelles Verzeichnis." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Noch ausführlicher!" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "Es muss eine einzelne PDF Datei angegeben werden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -987,7 +1568,15 @@ msgstr "" "\n" "%prog konvertiert dateiname.rtf in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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 "" +"Diese RTF Datei hat ein Feature, das calibre nicht unterstützt. Konvertieren " +"Sie es in HTML und konvertieren Sie es erneut." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:19 msgid "" "%prog [options] mybook.txt\n" "\n" @@ -999,25 +1588,35 @@ msgstr "" "\n" "%prog konvertiert dateiname.txt in dateiname.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Gebe Autoren ein" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Gebe Kommentar ein" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" "Eine durch Kommata getrennte Liste von Etiketten, die angewendet werden " "sollen" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Benutzung:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "Benutzung: imp-meta file.imp" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Kein Dateiname angegeben." + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -1042,23 +1641,23 @@ msgstr "" "bei isbndb.com erstellt werden kann.\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "Die ISBN des Buches, für das Sie Metadaten abrufen möchten." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "Der Autor des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "Der Titel des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "Der Herausgeber des gesuchten Buches." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1066,16 +1665,16 @@ msgstr "" "Konnte aufgrund zu hoher Serverlast kein Umschlagbild abrufen. Bitte " "versuchen Sie es später wieder." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " nicht gefunden." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "LibraryThing.com Server Fehler. Versuchen Sie es später." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1100,98 +1699,227 @@ msgstr "Umschlagbild gespeichert unter" msgid "Usage: pdf-meta file.pdf" msgstr "Benutzung: pdf-meta dateiname.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Kein Dateiname angegeben." +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "Benutzung: rb-meta file.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [options] dateiname.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "Original MOBI HTML gespeichert in" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Häufig benutzte Verzeichnisse" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" +"Periodisch heruntergeladenen Inhalt automatisch auf das Gerät übertragen" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" +"Das zu verwendende Format bei der Speicherung einzelner Dateie auf die " +"Festplatte" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Bestätigung vor dem Löschen" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "Schaltflächengröße der Symbolleiste" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Zeige Schaltflächenbeschriftung in der Symbolleiste" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Aufteilung des Hauptfensters" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Benachrichtigen, wenn eine neue Version verfügbar ist" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Benutze römische Ziffern für Seriennummerierung" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" +"Anzahl der Umschlagbilder, die im Cover-Ansicht Modus angezeit werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Voreinstellungen für Konvertierung zu LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Optionen für den LRF eBook Viewer" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Gerät ist nicht mehr verbunden." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Geräteinformationen erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Liste der Bücher auf dem Gerät erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Metadaten zum Gerät senden" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "%d Bücher auf das Gerät laden" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Bücher vom Gerät löschen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Bücher vom Gerät herunterladen" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Buch auf dem Gerät ansehen" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Titel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Bemerkung" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Pfad" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formate" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Dialog" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TextLabel" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:65 +msgid "&Previous" +msgstr "&Vorangegangenes" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:66 +msgid "&Next" +msgstr "&Nächstes" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:40 msgid "Choose Format" msgstr "Format wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" msgstr "" "Voreinstellungen für die Konvertierung von Comics (CBR/CBZ Dateien) setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" msgstr "Einstellungen für das Konvertieren &s setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" msgstr "&Titel:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" msgstr "&Autor(en):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" msgstr "A&nzahl der Farben:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Profil:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" msgstr "&Normalisieren deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" msgstr "Verhältnis &beibehalten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" msgstr "&Schärfen deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" msgstr "&Querformat" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 -msgid "Dont so&rt" -msgstr "Nicht sortieren" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "Nicht so&rtieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "Von &rechts nach links" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +msgid "De&speckle" +msgstr "Ent&körnung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "&Weite" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:23 msgid "Basic" @@ -1201,53 +1929,60 @@ msgstr "Einfach" msgid "Advanced" msgstr "Erweitert" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "<br>Muss ein Verzeichnis sein." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Ortsangabe der Datenbank ungültig " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Ortsangabe der Datenbank ungültig" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Muss ein Verzeichnis sein." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Ortsangabe der Datenbank ungültig " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "Ortsangabe der Datenbank ungültig.<br>Speichern nicht möglich " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "Komprimiere Datenbank. Das kann etwas dauern..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "Komprimiere Datenbank..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Konfiguration" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "Speicherort der Bücherdatenbank (&library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" +msgstr "" +"Speicher&ort der eBooks (Die eBooks werden in Verzeichnissen nach Autoren " +"sortiert gespeichert und die Metadaten werden in der Datei metadata.db " +"gespeichert)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Zu einem neuen Ort der Datenbank wechseln" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1255,43 +1990,43 @@ msgstr "Zu einem neuen Ort der Datenbank wechseln" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "&Römische Ziffern für Serien Nummerierung verwenden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" "A&nzahl der Umschlagbilder, die (nach einem Neustart) in der Cover-Ansicht " "angezeigt werden:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "Benachrichtigung anzeigen, wenn &neue Version verfügbar ist" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "Nach einer Bestätigung vor dem Löschen von Dateien fragen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "Format zur &Speicherung einer Datei:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "&Priorität der Konvertierungsaufträge:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "Voreinstellung für Zei&tüberschreitung bei Netzwerkverbindungen:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" @@ -1299,61 +2034,78 @@ msgstr "" "Voreinstellung der Zeitüberschreitung für Netzwerkabrufe festsetzen (Gilt " "immer dann, wenn aus dem Internet Informationen abgerufen werden sollen)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " Sekunden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "Sprache wäh&len (erfordert Neustart):" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "Das voreingestellte Ausgabeformat für eBook Konvertierungen." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "EPUB" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "&Ausgabeformat:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Groß" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Mittel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Klein" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "&Größe der Schaltflächen in der Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "Zeige &Text in Schaltflächen der Symbolleiste" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "Si&chtbare Spalten in Bibliothek-Ansicht wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Häufig benutzte Verzeichnisse" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" "Ein Verzeichnis zur Liste der häufig genutzten Verzeichnisse hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" "Ein Verzeichnis von der Liste der häufig genutzten Verzeichnisse entfernen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Freier unbenutzter Festplattenspeicher der Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "Datenbank &komprimieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "&Meta-Daten aus dem Dateinamen" @@ -1361,10 +2113,366 @@ msgstr "&Meta-Daten aus dem Dateinamen" msgid "ERROR" msgstr "FEHLER" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "Auf einmal in EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "%s in EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Meta-Daten" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Look & Feel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Seiteneinrichtung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Ermittlung der Kapitel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" +"Geben Sie Metadaten wie Titel und Autor des Buches an.\n" +"\n" +"Metadaten werden sowohl in der Datenbank als auch in der erstellten EPUB " +"Datei aktualisiert." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" +"Passen Sie das Aussehen der erzeugten EPUB Datei durch die Angabe von Dingen " +"wie Schriftgrößen an." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" +"Geben Sie die Einstellungen für das Seitenlayout, z.B. die Ränder, an." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "Feineinstellung der Erkennung von Kapitel- und Absatzüberschriften." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "Wählen Sie das Umschlagbild für " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Lesen nicht möglich" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Sie haben nicht die nötigen Rechte, um diese Datei zu lesen: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Fehler beim Lesen der Datei" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Es trat ein Fehler beim Lesen dieser Datei auf: <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " ist kein gültiges Bild" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Konvertierung nicht möglich" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "Dieses Buch hat keine Formate verfügbar" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Keine verfügbaren Formate" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" +"Kann %s nicht konvertieren, da dieses Buch nicht den bekannten Formaten " +"entspricht" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "Wählen Sie das Format, das in EPUB konvertiert werden soll" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "In EPUB konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Umschlagbild" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "&Umschlagbild ändern:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Nach Umschlagbild durchsuchen..." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Um&schlagbild der Quelldatei verwenden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Titel: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Titel dieses Buches ändern" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Autor(en): " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Autor dieses Buches ändern. Mehrere Autoren sollten durch Kommata getrennt " +"werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "So&rtierung nach Autor:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Herausgeber: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Herausgeber dieses Buches ändern" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "&Etiketten: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" +"Etiketten klassifizieren das Buch. Besonders wichtig bei der Suche nach " +"Büchern. <br><br>Sie können für Etiketten durch Kommata getrennte Wörter " +"oder Sätze verwenden." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Serien:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Liste der bekannten Serien. Sie können neue Serien hinzufügen." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Index der Serien." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Buch " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "En&codierung der Quelldatei:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "&CSS überschreiben" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "&Linker Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr " Punkt" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "&Rechter Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "&Oberer Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "&Unterer Rand:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "Automatische Kapitel Erkennung" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "&XPath:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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 "" +"<!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;\">Sie können kontrollieren, " +"wie calibre Kapitel erkennt, indem Sie einen XPath Ausdruck verwenden. Eine " +"Anleitung zur Benutzung von XPath Ausdrücken finden Sie im " +"englischsprachigen <a " +"href=\"https://calibre.kovidgoyal.net/user_manual/xpath.html\"><span " +"style=\" text-decoration: underline; color:#0000ff;\">XPath " +"Tutorial</span></a></p></body></html>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375 +msgid "Chapter &mark:" +msgstr "Kapitel &Markierung:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "Automatisches &Inhaltsverzeichnis" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" +"Anzahl der Vernküpfungen, die zum Inhaltsverzeichnis hinzugefügt werden" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "Erkannte Kapitel &nicht zum Inhaltsverzeichnis hinzufügen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "Kapitel Grenzwer&t" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" +"&Verwendung des automatisch erstellten Inhaltsverzeichnisses erzwingen" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Autor(en)" @@ -1457,36 +2565,6 @@ msgstr "Aktive Aufträge" msgid "&Stop selected job" msgstr "Ausgewählten Auftrag &stoppen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Meta-Daten" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Look & Feel" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Seiteneinrichtung" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Ermittlung der Kapitel" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Keine verfügbaren Formate" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" -"Kann %s nicht konvertieren, da dieses Buch nicht den bekannten Formaten " -"entspricht" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Wählen Sie das Format, das zu LRF konvertiert werden soll" @@ -1496,33 +2574,10 @@ msgid "Convert %s to LRF" msgstr "Konvertiere %s in LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Voreinstellungen zur Konvertierung wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "Lesen nicht möglich" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "Sie haben nicht die nötigen Rechte, um diese Datei zu lesen: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Fehler beim Lesen der Datei" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "<p>Es trat ein Fehler beim Lesen dieser Datei auf: <br /><b>" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " ist kein gültiges Bild" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1572,10 +2627,6 @@ msgstr "" "Seiteneinstellungen wie Ränder und die Bildschirmgröße des Zielgeräts " "angeben." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "Feineinstellung der Erkennung von Kapitel- und Absatzüberschriften." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">Keine Hilfe verfügbar</font>" @@ -1584,281 +2635,156 @@ msgstr "<font color=\"gray\">Keine Hilfe verfügbar</font>" msgid "Bulk convert ebooks to LRF" msgstr "eBooks auf einmal zu LRF konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Zu LRF konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Kategorie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Auswahlmöglichkeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Umschlagbild" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "&Umschlagbild ändern:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Nach Umschlagbild durchsuchen..." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Um&schlagbild der Quelldatei verwenden" - -#: /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:263 -msgid "&Title: " -msgstr "&Titel: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Titel dieses Buches ändern" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Autor(en): " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Autor dieses Buches ändern. Mehrere Autoren sollten durch Kommata getrennt " -"werden" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "So&rtierung nach Autor:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Herausgeber: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Herausgeber dieses Buches ändern" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "&Etiketten: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"<br><br>They can be any words or phrases, separated by commas." -msgstr "" -"Etiketten klassifizieren das Buch. Besonders wichtig bei der Suche nach " -"Büchern. <br><br>Sie können für Etiketten durch Kommata getrennte Wörter " -"oder Sätze verwenden." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Serien:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Liste der bekannten Serien. Sie können neue Serien hinzufügen." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Index der Serien." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Buch " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Ausgangsschrift&größe:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " Punkt" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Eingebundene Schriften" -#: /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:531 msgid "&Serif:" msgstr "&Serif:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif:" -#: /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:533 msgid "&Monospace:" msgstr "&Monospace:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -msgstr "En&codierung der Quelldatei:" - -#: /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:535 msgid "Minimum &indent:" msgstr "E&inrücken mindestens:" -#: /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:537 msgid "&Word spacing:" msgstr "&Wortabstand:" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Automatische &Rotation von Bildern einschalten" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "&Leerzeilen zwischen Paragraphen einfügen" -#: /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:541 msgid "Ignore &tables" msgstr "&Tabellen ignorieren" -#: /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:542 msgid "Ignore &colors" msgstr "Farben nicht bea&chten" -#: /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:543 msgid "&Preprocess:" msgstr "&Vorbearbeiten:" -#: /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:544 msgid "Header" msgstr "Kopfzeile" -#: /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:545 msgid "&Show header" msgstr "Kopfzeile an&zeigen" -#: /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:546 msgid "&Header format:" msgstr "&Kopfzeilenformat:" -#: /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:547 msgid "Override<br>CSS" msgstr "CSS<br>überschreiben" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "&Linker Rand:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " Pixel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "&Rechter Rand:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "&Oberer Rand:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "&Unterer Rand:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "&Konvertiere Tabellen in Bilder (gut bei großen/komlexen Tabellen)" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "&Faktor der Textgröße in gerenderten Tabellen:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Auf Titel basierende Ermittlung" -#: /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:560 msgid "&Disable chapter detection" msgstr "Kapitel Ermittlung &deaktivieren" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "&Regulärer Ausdruck:" -#: /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:562 msgid "Add &chapters to table of contents" msgstr "&Kapitel zum Inhaltsverzeichnis hinzufügen" -#: /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:563 msgid "Don't add &links to the table of contents" msgstr "Keine &Links zum Inhaltsverzeichnis hinzufügen" -#: /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:564 msgid "Tag based detection" msgstr "Auf Etiketten basierende Ermittlung" -#: /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:565 msgid "&Page break before tag:" msgstr "&Seitenumbruch vor Element:" -#: /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:566 msgid "&Force page break before tag:" msgstr "Seitenumbruch vor Element &erzwingen:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Seitenumbruch vor &Attribut erzwingen:" -#: /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:568 msgid "Detect chapter &at tag:" msgstr "Erkenne K&apitel bei Element:" -#: /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:569 msgid "Help on item" msgstr "Hilfe für das jeweilige Objekt" -#: /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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1868,8 +2794,8 @@ msgstr "" "<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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1879,17 +2805,17 @@ msgid "Edit Meta information" msgstr "Meta-Informationen bearbeiten" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Meta-Informationen" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "S&ortierung nach Autor: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1898,19 +2824,19 @@ msgstr "" "Dickens\" zum Beispiel als \"Dickens, Charles\"." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Bewertung:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Bewertung dieses Buches: 0-5 Sterne" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " Sterne" @@ -1920,8 +2846,8 @@ msgstr "&Etiketten hinzufügen: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Etiketten-Editor öffnen" @@ -1935,7 +2861,7 @@ msgstr "" "Durch Kommata getrennte Liste der Etiketten, die von den Büchern entfernt " "werden. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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> " @@ -1945,65 +2871,72 @@ msgstr "" "<b>LibraryThing.com</b> an. <br/>Insofern Sie dies nicht besitzen, können " "Sie sich kostenlos <a href='http://www.librarything.com'>anmelden</a>! </p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "<b>Konnte kein Umschlagbild abrufen.</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "Konnte kein Umschlagbild abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "Kann kein Umschlagbild abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Sie müssen die ISBN für dieses Buch angeben." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Meta-Informationen bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "Tausche Autor und Titel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +msgid "" +"Automatically create the author sort entry based on the current author entry" +msgstr "" +"Atuomatisch den Eintrag für die Sortierung nach Autor basierend auf dem " +"aktuellen Autor erstellen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 msgid "Remove unused series (Series that have no books)" msgstr "Unbenutzte Serien entfernen (Serien ohne Bücher)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Meta-Daten vom Server abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Verfügbare Formate" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Ein neues Format für dieses Buch zur Datenbank hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "Markierte Formate dieses Buches aus der Datenbank löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Umschlagbild vom Server abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" "Benutzername und/oder Passwort Ihres Kontos bei LibraryThing.com ändern" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Passwort ändern" @@ -2032,13 +2965,15 @@ msgid "Tag" msgstr "Etikett" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Serie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Format" @@ -2376,11 +3311,11 @@ msgstr "Regulärer Ausdruck Gruppenname (?P<title>)" #: /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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "Kein Treffer" @@ -2413,103 +3348,102 @@ msgstr "Regulärer Ausdruck Gruppenname (?P<series_index>)" msgid "ISBN:" msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Auftrag" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Status" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Fortschritt" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "Laufzeit" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "Fehler" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "Unbekannter Auftrag" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "Fertig" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Fehler" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" msgstr "Abwarten und Tee trinken..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "Bei der Arbeit..." -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "Kann Auftrag nicht abbrechen" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." -msgstr "" -"Kann Aufträge nicht abbrechen, die mit dem Gerät kommunizieren, da dies zu " -"Datenverlust führen kann." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "Kann Aufträge, die mit dem Gerät kommunizieren, nicht abbrechen" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "Kann schon fertiggestellte Aufträge nicht abbrechen." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "Auftrag wird schon ausgeführt" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "Kann Auftrag auf Warteliste nicht abbrechen" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Keine" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Etiketten" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formate" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Buch <font face=\"serif\">%s</font> von %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "Doppelklick ermöglicht <b>Bearbeitung</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Größe (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Datum" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Bewertung" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Pfad" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Zeitstempel" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "Suche (Zur erweiterten Suche die Schaltfläche links klicken)" @@ -2529,15 +3463,15 @@ msgstr "Mit Trennstrich versehen" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "<b>Änderungen werden erst nach einem Neustart wirksam.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" msgstr " - LRF Vorschau" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "<b>Keine Treffer</b> für die Suchworte <i>%s</i> gefunden." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "Keine Treffer gefunden" @@ -2581,11 +3515,11 @@ msgstr "eBook öffnen" msgid "Configure" msgstr "Konfigurieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Fehler bei der Kommunikation mit dem Gerät" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" @@ -2593,42 +3527,42 @@ msgstr "" "<p>Hilfe gibt es online bei <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "<b>%s</b>: %s von <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "An Hauptspeicher senden" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "An Speicherkarte senden" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "und aus der Datenbank löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "Auf die Speicherkarte senden (Voreinstellung)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Meta-Daten einzeln bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Meta-Daten auf einmal bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "Bücher aus einem einzelnen Verzeichnis hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2636,7 +3570,7 @@ msgstr "" "Bücher rekursiv hinzufügen (Ein Buch pro Verzeichnis, setzt voraus, dass " "jede eBook Datei das gleiche Buch in einem unterschiedlichen Format enthält)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2644,61 +3578,75 @@ msgstr "" "Bücher rekursiv hinzufügen (Mehrere Bücher pro Verzeichnis, setzt voraus, " "dass jede eBook Datei ein anderes Buch enthält)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Auf Festplatte speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "Auf Festplatte in ein einziges Verzeichnis speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "Nur das %s Format auf Festplatte speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Vorschau" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "Spezielles Format ansehen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Einzeln konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Auf einmal konvertieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" -msgstr "Voreinstellungen für die Konvertierung zu LRF Dateien setzen" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "Voreinstellung für Konvertierung eingeben" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "Voreinstellungen für die Konvertierung von Comics setzen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr " gefunden." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "Schlechter Datenbank Standort" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "Wählen Sie einen Speicherort für Ihre eBook Bibliothek." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "Migriere Datenbank" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "Gerät: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " gefunden." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "Angeschlossen: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "Gerätedatenbank ist beschädigt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2729,8 +3677,8 @@ msgstr "" " </ol>\n" " " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2738,60 +3686,60 @@ msgstr "" "<p>Es existieren bereits Bücher mit dem selben Titel in der Datenbank. " "Sollen die folgenden Bücher trotzdem hinzugefügt werden?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "Duplikate gefunden!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "Lade Bücher auf das Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Gerätespeicher voll" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>Es können keine Bücher mehr auf das Gerät geladen werden, da der " "Gerätespeicher voll ist " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "Bestätigen Sie das Löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "Sind Sie sicher, dass Sie diese %d Bücher löschen wollen?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "Lösche Bücher vom Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "Kann Metadaten nicht bearbeiten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Keine Bücher ausgewählt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "Sende Bücher an das Gerät." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "Keine geeigneten Formate" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" @@ -2799,11 +3747,11 @@ msgstr "" "Die folgenden Bücher konnten nicht auf das Gerät geladen werden, da keine " "geeigneten Formate vorhanden sind:<br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "Speichern auf Festplatte nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" @@ -2811,95 +3759,60 @@ msgstr "" "<p>Die folgenden Bücher konnten nicht auf die Festplatte gespeichert werden, " "da das %s Format für sie nicht verfügbar ist:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "Konnte einige eBooks nicht speichern" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "Nachrichten abrufen von " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "Rufe Nachrichten ab von " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "Nachrichten abgerufen. Übertragung ans Gerät läuft." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "Konvertierung nicht möglich" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "Starte Massenkonvertierung von %d Büchern" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "Konvertiere Buch %d von %d (%s)" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -msgid "" -"<p>Could not convert %d of %d books, because no suitable source format was " -"found.<ul>%s</ul>" -msgstr "" -"<p>Konnte %d von %d Büchern nicht konvertieren, da kein brauchbares " -"Ursprungsformat gefunden werden konnte.<ul>%s</ul>" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:843 -msgid "Could not convert some books" -msgstr "Konnte einige Bücher nicht konvertieren" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "Konvertiere Comic %d von %d (%s)" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "Buch konvertieren: " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "Comic konvertieren: " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Kein Buch ausgewählt" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "Ansehen nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "Format zur Vorschau wählen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "%s hat keine verfügbaren Formate." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "Konfiguration nicht möglich" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "Konfiguration nicht möglich während Aufträge abgearbeitet werden." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "Kopiere Datenbank nach " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "Kopiere Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "Kopiere Bibliothek nach " + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "Ungültige Datenbank" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2907,23 +3820,23 @@ msgstr "" "<p>Es existiert bereits eine ungültige Datenbank in %s, bitte löschen Sie " "diese, bevor sie die bestehende Datenbank verschieben.<br>Fehler: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "Konnte Datenbank nicht verschieben" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "Es ist keine weitere Information verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "Es ist keine weitere Information über Bücher auf dem Gerät verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Fehler in der Kommunikation zum Gerät" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2931,15 +3844,16 @@ msgstr "" "Es trat ein Fehler in der Kommunikation mit dem Gerät auf. Bitte entfernen " "und schließen Sie das Gerät wieder an und - oder starten Sie neu." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "Konvertierungsfehler" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "Datenbank existiert nicht" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." @@ -2947,7 +3861,11 @@ msgstr "" "Das Verzeichnis, in dem die Datenbank sein sollte: %s existiert nicht mehr. " "Bitte wählen Sie einen neuen Ort für die Datenbank aus." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "Wählen Sie einen neuen Speicherort für die Datenbank" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" @@ -2955,7 +3873,7 @@ msgstr "" "<span style=\"color:red; font-weight:bold\">Letzte Version: <a " "href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " @@ -2965,27 +3883,27 @@ msgstr "" "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">neuen Features</a> an. " "Möchten Sie die Download Seite besuchen?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "Neue Version verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "Erweiterte Suche" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Suche:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -2993,7 +3911,7 @@ msgstr "" "Liste der Bücher nach Titel oder Autor durchsuchen<br><br>Durch Leerzeichen " "getrennte Wörter werden mit \"UND\" verknüpft" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -3002,60 +3920,68 @@ msgstr "" "durchsuchen<br><br>Durch Leerzeichen getrennte Wörter werden mit \"UND\" " "verknüpft" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Quick Search löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "Übereinstimmung mit irgendeinem" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "Übereinstimmung mit allen" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Bücher hinzufügen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Bücher entfernen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Löschen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Meta-Informationen editieren" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "An Reader übertragen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Nachrichten abrufen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "F" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "In eBooks umwandeln" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "C" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "V" @@ -3068,7 +3994,7 @@ msgstr "" "stderr). Hilfreich bei Fenstern in denen GUI Programme nicht über Output-" "Streams verfügen." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "FEHLER: Unbehandelte Ausnahme" @@ -3089,23 +4015,23 @@ msgstr "" msgid "Custom news sources" msgstr "Individuelle Nachrichtenquellen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Aufträge:" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "Ein Klick zeigt die aktiven Aufträge." -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "Klicken Sie, um die Bücher in der Cover-Ansicht zu durchsuchen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "Klicken Sie, um die Cover-Ansicht zu verlassen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" @@ -3113,19 +4039,71 @@ msgstr "" "<p>Die Cover-Ansicht ist gesperrt.<br>Der Import des Pictureflow Moduls " "schlug fehl:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "Klicken Sie, um die Bücher anhand von Etiketten zu durchsuchen" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "Autoren" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "Herausgeber" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "Buch konvertieren: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "Comic konvertieren: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Starte Massenkonvertierung von %d Büchern" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "Konvertiere Buch %d von %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" +"<p>Konnte %d von %d Büchern nicht konvertieren, da kein brauchbares " +"Ursprungsformat gefunden werden konnte.<ul>%s</ul>" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "Konnte einige Bücher nicht konvertieren" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Nachrichten abrufen von " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" msgstr "Ungültiger regulärer Ausdruck" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" msgstr "Ungültiger regulärer Ausdruck: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Bibliothek" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3133,7 +4111,7 @@ msgstr "" "Reader\n" "%s verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3141,40 +4119,44 @@ msgstr "" "Karte\n" "%s verfügbar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "Ein Klick zeigt die Liste der auf dem Computer vorhandenen Bücher" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "" "Ein Klick zeigt die Liste der im Hauptspeicher des Geräts vorhandenen Bücher" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" "Ein Klick zeigt die Liste der auf der Speicherkarte des Geräts vorhandenen " "Bücher" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" -"Pfad zur Datenbank von calibre. Die Voreinstellung ist der in den " -"Einstellungen gespeicherte Pfad." +"Pfad zur calibre Bibliothek. Die Voreinstellung ist der in den Einstellungen " +"gespeicherte Pfad." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "Benutze Bibliothek in" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" "%prog list [options]\n" "\n" -"Listet die in der Datenbank von calibre verfügbaren Bücher auf. \n" +"Listet die vorhandenen Bücher in der calibre Datenbank auf.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3187,7 +4169,7 @@ msgstr "" "Verfügbare Felder: %s\n" "Voreinstellung: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" @@ -3197,11 +4179,11 @@ msgstr "" "Verfügbare Felder: %s\n" "Voreinstellung: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "Sortiere Ergebnisse in aufsteigender Reihenfolge" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 " @@ -3211,15 +4193,15 @@ msgstr "" "sehen Sie sich bitte die Dokumentation, die die Suche betrifft, im " "Benutzerhandbuch an. Voreinstellung ist, keine Filterung durchzuführen." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "Ungültige Felder. Verfügbare Felder:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "Ungültiges Sortierungs-Feld. Verfügbare Felder:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" @@ -3227,21 +4209,21 @@ msgstr "" "Die folgenden Bücher wurden nicht hinzugefügt, da sie schon in der Datenbank " "vorhanden sind (siehe --duplicates Option):" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" "%prog add [options] Datei1 Datei2 Datei3 ...\n" "\n" "Fügt die angegebenen Dateien als Bücher zur Datenbank hinzu. Sie können auch " -"Verzeichnisse angeben, sehen Sie sich dazu die zu den Verzeichnissen " -"gehörigen Optionen weiter unten an. \n" +"Verzeichnisse angeben, vergleichen\n" +"Sie dazu die auf Verzeichnisse bezogenen Optionen unten.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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" @@ -3250,11 +4232,11 @@ msgstr "" "und alle Dateien in diesem Verzeichnis sind verschiedene eBook Formate " "dieses einzelnen Buches" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "Verzeichnisse rekursiv verarbeiten" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." @@ -3262,12 +4244,12 @@ msgstr "" "Füge Bücher zur Datenbank hinzu, auch wenn diese schon vorhanden sind. Der " "Abgleich erfolgt aufgrund des Titels der Bücher." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" "Sie müssen wenigstens eine Datei auswählen, die hinzugefügt werden soll" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3282,11 +4264,11 @@ msgstr "" "(Sie erhalten die ID Zahlen durch die Benutzung des Befehls list). Zum " "Beispiel: 23,34,57-85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "Sie müssen wenigstens ein Buch auswählen, das entfernt werden soll" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3300,15 +4282,15 @@ msgstr "" "gekennzeichneten logischen Buches hinzu. Sie erhalten die ID durch den list " "Befehl. Falls das Format schon vorhanden ist, wird es ersetzt.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "Sie müssen eine ID und eine eBook Datei angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "eBook Datei muss eine Endung haben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3325,35 +4307,35 @@ msgstr "" "eine Dateiendung wie LRF oder TXT oder EPUB sein. Falls das logische Buch im " "entsprechenden Format nicht vorliegt, passiert gar nichts.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "Sie müssen eine ID und ein Format (Dateiendung) angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" "\n" -"%prog show_metadata [options] id\n" +"%prog show_metadata [options] ID\n" "\n" -"Zeige die in der calibre Datenbank gespeicherten Meta-Daten für das durch " -"die ID erkannte Buch. \n" -"\"id\" ist eine ID Nummer des Befehls \"list\". \n" +"Zeigt die in der calibre Datenbank gespeicherten Metadaten für das durch die " +"ID angegebene Buch.\n" +"ID ist eine ID Nummer des Befehls list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "Drucke Meta-Daten als OPF (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "Sie müssen eine ID angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3361,89 +4343,143 @@ msgid "" "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" +"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 "" "\n" -"%prog set_metadata [options] id /verzeichnis/zu/metadata.opf\n" +"%prog set_metadata [options] ID /pfad/zu/metadaten.opf\n" "\n" -"Übernehme die Meta-Daten, die in der calibre Datenbank für das durch die ID " -"erkannte Buch gespeichert werden,\n" -"aus der OPF Datei metadata.opf. \"id\" ist eine ID Nummer des Befehls " -"\"list\". Sie erhalten \n" -"einen Eindruck über das OPF Format, wenn Sie die --as-opf Option mit dem \n" -"Befehl show_metadata verwenden.\n" +"Stellt die in der calibre Datenbank gespeicherten Metadaten für das durch " +"die ID angegebene Buch\n" +"ein auf die Metadaten der OPF Datei metadata.opf. ID ist eine ID Nummer des " +"Befehls list. Sie\n" +"erhalten einen ersten Eindruck vom OPF Format durch die Verwendung der --as-" +"opf Option mit dem\n" +"show_metadata Befehl.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "Geben Sie eine ID und eine Meta-Daten Datei an" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" -"%prog export [options] ids \n" +"%prog export [options] IDs\n" "\n" -"Exportiert die durch IDs angegebenen Bücher (als durch Kommata getrennte " -"Liste) in das Dateisystem.\n" -"Der Export speichert alle Formate des Buches, sein Umschlagbild und die Meta-" -"Daten (in \n" -"einer OPF Datei). Sie erhalten ID Nummern mit dem Befehl \"list\". \n" +"Exportiert die durch IDs (eine durch Kommata getrennte Liste) angegebenen " +"Bücher in das Dateisystem.\n" +"Der Exportvorgang speichert alle Formate der Bücher, ihre Umschlagbilder und " +"Metadaten (in\n" +"einer opf Datei). Die ID Nummern erhalten Sie mit dem Befehl list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" "Exportiere alle Bücher der Datenbank, die Liste der IDs wird ignoriert." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "Exportiere Bücher in das angegebene Verzeichnis. Voreinstellung ist" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "Exportiere alle Bücher in ein einziges Verzeichnis" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" "Erstelle Dateinamen mit \"Autor - Titel\" anstelle von \"Titel - Autor\"" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "Sie müssen IDs oder die %s Option angeben" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" "%%prog command [options] [arguments]\n" "\n" -"%%prog ist die Befehlszeilenschnittstelle zur Bücher Datenbank von calibre. " +"%%prog ist die Befehlszeilenschnittstelle zur calibre eBook Datenbank.\n" "\n" -"\n" -"command ist eines der folgenden:\n" +"command ist eines dieser Befehle:\n" " %s\n" -" \n" -"Für Hilfe zu einem bestimmten Befehl (command): %%prog command --help\n" +"\n" +"Sie erhalten Hilfe zu einem bestimmten Befehl mit: %%prog command --help\n" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "<p>Kopiere Bücher nach %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "Kopiere <b>%s</b>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "<p>Migriere alte Datenbank zu eBook Bibliothek in %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "Komprimiere Datenbank" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "Konnte Arbeitsprozess nicht starten." +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "Auftrag durch Benutzer unterbrochen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sBenutzung%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Erstellt von " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "Pfad zur Datenbank in der die Bücher gespeichtert sind" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "Verhaltensmuster zum Erraten der Metadaten aus den Dateinamen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "Zugangsschlüssel für isbndb.com" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" +"Voreinstellung der Zeitüberschreitung bei Netzwerkverbindungen (in Sekunden)" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "Pfad zum Verzeichnis, in dem die Bibliothek gespeichert ist" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "Sprache, in der die Benutzer-Oberfläche dargestellt wird" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "Konnte die fontconfig library nicht initialisieren" @@ -3474,7 +4510,153 @@ msgstr "Feed unbekannt" msgid "Untitled article" msgstr "Artikel ohne Titel" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" +"Einstellungen zur Kontrolle des Abrufs von regelmäßig erscheinendem Inhalt " +"aus dem Netz." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "Download-Engine anpassen" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Timeout in Sekunden beim Warten auf eine Antwort vom Server. Voreinstellung: " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Kleinstes Intervall in Sekunden zwischen aufeinander folgenden Abrufen. " +"Voreinstellung ist %default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"Zeichenkodierung für Webseiten, die zu laden versucht werden. In der " +"Voreinstellung wird versucht, die Kodierung zu erraten." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Nur Links, die diesem Regulären Ausdruck entsprechen, werden verfolgt. Diese " +"Option kann mehrmals angegeben werden, somit werden Links verfolgt, solange " +"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden alle " +"Links verfolgt." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Jeder Link, der diesem Regulären Ausdruck entspricht, wird ignoriert. Diese " +"Option kann mehrmals angegeben werden, somit werden Links ignoriert, solange " +"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden keine " +"Links ignoriert. Falls beide --filter-regexp und --match-regexp angegeben " +"sind, wird --filter-regexp zuerst angewendet." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Lade CSS Stylesheets nicht herunter." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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 "" +"Geben Sie eine Liste von Feeds zum Download an. Zum Beispiel: \n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"Wenn Sie diese Option wählen, wird jedes Argument %prog ignoriert und die " +"Voreinstellung zum Download der Feeds verwendet." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "Noch ausführlicher bei der weiteren Verarbeitung vorgehen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"Der Titel für dieses Rezept. Wird als Titel für alle eBooks benutzt, die aus " +"den geladenen Feeds erstellt wurden." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" +"Benutzername für Webseiten, die einen Login für den Inhaltsabruf benötigen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" +"Passwort für Webseiten, die einen Login für den Inhaltsabruf benötigen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Anzahl der Links in die Tiefe, die vom Feed aus verfolgt werden sollen. " +"Voreinstellung %default" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"Das Verzeichnis, in dem die geladenen Feeds gespeichert werden. " +"Voreinstellung auf das aktuelle Verzeichnis." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "Fortschrittsbalken nicht anzeigen" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "Sehr ausführliche Ausgabe, hilfreich bei der Fehlersuche." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Hilfreich zur Entwicklung von Rezepten. Erzwingt maximal 2 Artikel pro Feed " +"und lädt höchstens 2 Feeds." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3514,145 +4696,81 @@ msgstr "" "Verfügbare installierte Rezepte:\n" "%s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" "Einstellungen für web2disk (um von Feeds verlinkte Webseiten abzurufen)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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 "" -"Geben Sie eine Liste von Feeds zum Download an. Zum Beispiel: \n" -"\"['http://feeds.newsweek.com/newsweek/TopNews', " -"'http://feeds.newsweek.com/headlines/politics']\"\n" -"Wenn Sie diese Option wählen, wird jedes Argument %prog ignoriert und die " -"Voreinstellung zum Download der Feeds verwendet." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 -msgid "Be more verbose while processing." -msgstr "Noch ausführlicher bei der weiteren Verarbeitung vorgehen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -msgid "" -"The title for this recipe. Used as the title for any ebooks created from the " -"downloaded feeds." -msgstr "" -"Der Titel für dieses Rezept. Wird als Titel für alle eBooks benutzt, die aus " -"den geladenen Feeds erstellt wurden." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:47 -msgid "Username for sites that require a login to access content." -msgstr "" -"Benutzername für Webseiten, die einen Login für den Inhaltsabruf benötigen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" -"Passwort für Webseiten, die einen Login für den Inhaltsabruf benötigen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" -"Anzahl der Links in die Tiefe, die vom Feed aus verfolgt werden sollen. " -"Voreinstellung %default" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "" -"The directory in which to store the downloaded feeds. Defaults to the " -"current directory." -msgstr "" -"Das Verzeichnis, in dem die geladenen Feeds gespeichert werden. " -"Voreinstellung auf das aktuelle Verzeichnis." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "Fortschrittsbalken nicht anzeigen" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "Sehr ausführliche Ausgabe, hilfreich bei der Fehlersuche." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -msgid "" -"Useful for recipe development. Forces max_articles_per_feed to 2 and " -"downloads at most 2 feeds." -msgstr "" -"Hilfreich zur Entwicklung von Rezepten. Erzwingt maximal 2 Artikel pro Feed " -"und lädt höchstens 2 Feeds." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "Rufe Feeds ab..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "Nachrichtenquelle unbekannt" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "Download beendet" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "Der Download der folgenden Artikel schlug fehl:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr " von " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "Der Download von Teilen der folgenden Artikel schlug fehl:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "\tFehlgeschlagene Verknüpfungen:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" "Konnte Artikel nicht abrufen. Der erneute Start mit --debug zeigt mögliche " "Gründe an" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "Feeds der Index Seite erhalten" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "Versuche Umschlagbild zu laden..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "Starte Download von [%d Thread(s)]..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "Feeds wurden nach %s heruntergeladen" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "Konnte Umschlagbild nicht laden: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "Lade Umschlagbild von %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "Artikel ohne Titel" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" @@ -3662,23 +4780,23 @@ msgstr "" "Artikel %s von %s geladen\n" "%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "Artikel geladen: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "Laden der Artikel fehlgeschlagen: %s von %s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "Laden der Artikel schlug fehl: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "Rufe Feed ab" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" @@ -3688,21 +4806,13 @@ msgstr "" "\n" "URL ist z.B. http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" "Grundverzeichnis, in das die URL gespeichert wird. Voreinstellung ist " "%default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Timeout in Sekunden beim Warten auf eine Antwort vom Server. Voreinstellung: " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3710,7 +4820,7 @@ msgstr "" "Maximale Zahl von einbezogenen Ebenen, z.B. Tiefe der Links, die verfolgt " "werden. Voreinstellung %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3718,51 +4828,6 @@ msgstr "" "Höchstzahl der Dateien, die geladen werden. Dies trifft nur auf Dateien aus " "<a href> Tags zu. Voreinstellung ist %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Kleinstes Intervall in Sekunden zwischen aufeinander folgenden Abrufen. " -"Voreinstellung ist %default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -msgid "" -"The character encoding for the websites you are trying to download. The " -"default is to try and guess the encoding." -msgstr "" -"Zeichenkodierung für Webseiten, die zu laden versucht werden. In der " -"Voreinstellung wird versucht, die Kodierung zu erraten." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:400 -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 "" -"Nur Links, die diesem Regulären Ausdruck entsprechen, werden verfolgt. Diese " -"Option kann mehrmals angegeben werden, somit werden Links verfolgt, solange " -"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden alle " -"Links verfolgt." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 -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 "" -"Jeder Link, der diesem Regulären Ausdruck entspricht, wird ignoriert. Diese " -"Option kann mehrmals angegeben werden, somit werden Links ignoriert, solange " -"sie einem Regulären Ausdruck entsprechen. In der Voreinstellung werden keine " -"Links ignoriert. Falls beide --filter-regexp und --match-regexp angegeben " -"sind, wird --filter-regexp zuerst angewendet." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "Lade CSS Stylesheets nicht herunter." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche." diff --git a/src/calibre/translations/nl.po b/src/calibre/translations/nl.po index ae1a5d1092..3456aed421 100644 --- a/src/calibre/translations/nl.po +++ b/src/calibre/translations/nl.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-07-29 07:48+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-04 01:49+0000\n" "Last-Translator: Marc van den Dikkenberg <Unknown>\n" "Language-Team: Dutch <nl@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: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" #~ msgid "" @@ -50,9 +50,22 @@ msgstr "" #~ msgid "mybook.epub" #~ msgstr "mijnboek.epub" +#~ msgid "&Location of books database (library1.db)" +#~ msgstr "&Locatie van boek database )library1.db)" + #~ msgid "&Access Key;" #~ msgstr "&Toegangssleutel" +#~ msgid "" +#~ "Cannot kill jobs that are communicating with the device as this may cause " +#~ "data corruption." +#~ msgstr "" +#~ "Opdrachten die communiceren met de lezer kunnen niet worden afgebroken omdat " +#~ "dit data corruptie kan veroorzaken." + +#~ msgid "Cannot kill already completed jobs." +#~ msgstr "Opdrachten die al zijn voltooid kunnen niet worden afgebroken." + #~ msgid "Cannot kill waiting jobs." #~ msgstr "Wachtende opdrachten kunnen niet worden afgebroken." @@ -69,14 +82,45 @@ msgstr "" #~ "Schrijf de tekst hieronder in een bestand genaamd recipe.py en stuur deze " #~ "naar je vrieden, zodat zij dit recept ook kunnen gebruiken." +#~ msgid "Copying database to " +#~ msgstr "copieer database naar " + +#~ msgid "" +#~ "Path to the calibre database. Default is to use the path stored in the " +#~ "settings." +#~ msgstr "" +#~ "Pad naad de Calibre database. Standaard word het pad gebruikt dat is " +#~ "opgeslagen in de instellingen." + +#~ msgid "" +#~ "%prog list [options]\n" +#~ "\n" +#~ "List the books available in the calibre database. \n" +#~ msgstr "" +#~ "%prog list [opties]\n" +#~ "\n" +#~ "Laat de boeken zien die beschikbaar zijn in de Calibre database. \n" + +#~ 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 "" +#~ "%prog add [opties] bestand1 bestand2 bestand3 ...\n" +#~ "\n" +#~ "Voeg de gespecificeerde bestanden als boeken toe aan de database. Je kunt " +#~ "ook folders opgeven, zie de folder-gerelateerde opties hieronder. \n" + #~ 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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -86,53 +130,462 @@ msgstr "" #~ "<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" +#~ "</style></head><body style=\" font-family:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "%sGebruik%s: %s\n" +#~ 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 "" +#~ "\n" +#~ "%prog show_metadata [opties] id\n" +#~ "\n" +#~ "Laat de metadata uit de Calibre database zien voor het boek geidentificeerd " +#~ "met het id. \n" +#~ "id is een id nummer van het list commando \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Gemaakt door " +#~ 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 "" +#~ "\n" +#~ "%prog set_metadata [opties] id /pad/naar/metadata.opf\n" +#~ "\n" +#~ "Definieer de metadata die is opgeslagen in de Calibre database voor het " +#~ "boek\n" +#~ "geidenticeerd met id uit het OPF bestand metadata.opf. id is een id nummer " +#~ "uit\n" +#~ "het list commando. Je kunt meer informatie voor het OPF formaat zien door\n" +#~ "--as-opf parameter op te geven bij het show_metadata commando.\n" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ 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 "" +#~ "%prog export [opties] ids \n" +#~ "\n" +#~ "Exporteer de boeken opgegeven als ids (een lijst gescheiden met komma's)\n" +#~ "naar het bestandssysteem. De exporteer operatie bewaard alle formaten van\n" +#~ "het boek, de cover en metadata (in een opf bestand) Je kunt id nummers zien\n" +#~ "via het list commando. \n" + +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "%prog [opties] comic.cb[z|r] \n" + +#~ msgid "Set defaults for conversion to LRF" +#~ msgstr "Zet standaarden voor conversie naar LRF" + +#~ msgid "Convert comic %d of %d (%s)" +#~ msgstr "Converteer comic %d van %d (%s)" + +#~ msgid "" +#~ "An XPath expression to detect chapter titles. The default is to consider " +#~ "<h1> or\n" +#~ "<h2> tags that contain the text \"chapter\" or \"book\" or \"section\" as " +#~ "chapter titles. \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 "" +#~ "Een XPath expressie om hoofdstuk titels te herkennen. Standaard zullen <h1> " +#~ "of <h2> tags die de tekst 'chapter', 'book' of 'section' bevatten als " +#~ "hoofdstuk titel worden aangemerkt. \n" +#~ "De gebruikte expressie moet een lijst van elementen evalueren. Om hoofstuk " +#~ "detectie uit te schakelen, gebruik de expressie \"/\". Zie de XPath " +#~ "handleiding in de Calibre gebruikers handboek voor meer help betreffende " +#~ "deze functie.\n" + +#~ msgid "Don't add detected chapters to the Table of Contents" +#~ msgstr "Voeg gevonden hoofdstukken niet toe aan de inhoudsopgave" + +#~ msgid "Don't add links in the root HTML file to the Table of Contents" +#~ msgstr "Voeg links in het hoofd HTML bestand niet toe aan de inhoudsopgave" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Convert a HTML file to an EPUB ebook. Follows links in the HTML file. \n" +#~ msgstr "" +#~ "%prog [opties] bestand.html\n" +#~ "\n" +#~ "Converteer een HTML bestand naar een EPUB eboek. Volg links in het HTML " +#~ "bestand. \n" + +#~ msgid "" +#~ "%prog [options] file.html\n" +#~ "\n" +#~ "Follow all links in an HTML file and collect them into the specified " +#~ "directory.\n" +#~ "Also collects any references resources like images, stylesheets, scripts, " +#~ "etc. \n" +#~ msgstr "" +#~ "%prog [opties] bestand.html\n" +#~ "\n" +#~ "Volg alle links in een HTML bestand en verzamel deze in de opgegeven " +#~ "folder.\n" +#~ "Verzamel ook alle referentie bronnen zoals plaatjes, stylesheets, scripts, " +#~ "enz. \n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "Schijf %s is niet gevonden. Probeer te herstarten." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "Er is geen geheugen kaart verbonden met de reader." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Opties voor de conversie naar EPUB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"Het uitvoer EPUB bestand. Indien niet opgegeven, zal het worden gegenereerd " +"uit de invoer naam." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "Beinvloed auto-detectie van de document structuur." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Onbekend" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "Een bron HTML bestand is nodig" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "Schrijf verwerkte HTML naar " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "Opties voor de verwerking van HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "De uitvoer folder. Standaard is de huidige folder." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "Karakter codering voor HTML bestanden. Standaard is auto detect." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Genereer de uitvoer in een zip bestand. Als deze optie is gekozen, dan moet -" +"-output de naam van een bestand zijn, niet de folder." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Configueer het volgen van links in HTML bestanden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" +"Volg links in HTML bestanden in de breedte. Standaard worden ze eerst in de " +"diepte gevolgd." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Maximum aantal recursieve lagen bij het volgen van links in HTML bestanden. " +"Deze waarde kan niet negatief zijn. Gebruik 0 aan te geven dan links in het " +"top HTML bestand niet zullen worden gevolgd." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Metadata van het gegenereerde eboek" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Titel. Standaard is auto-detect." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "De auteur(s) van het eboek, als lijst gescheiden met komma's." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Opties handig voor debuggen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" +"Geen meer informatie tijdens verwerking. Dit kan meerder malen worden " +"opgegeven om meer informatie te verkrijgen" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" +"Uitvoer HTML is \"mooi geprint\" om makkelijker door mensen leesbaar te zijn" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "%prog [opties] LITBESTAND" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "Output folder. Standaard is dit de huidige folder." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" +"Formatteer de markup in leesbaar formaat. Zinvolle witruimte kan hierdoor " +"gewijzigd worden." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "Handig voor Debugging" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "OEB boek bemaakt in" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "De titel. Standaard: bestandsnaam" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" @@ -140,49 +593,34 @@ msgstr "" "De auteur(s). Meerdere auteurs moeten met een komma van elkaar gescheiden " "worden. Standaard: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Onbekend" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Opmerking." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "Geef de categorie" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Zoeksleutel voor de titel" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Zoeksleutel voor de auteur" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Uitgeverij" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Pad naar het bestand met afbeelding om als omslag te gebruiken" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -190,11 +628,11 @@ msgstr "" "Als er een afbeeling is gevonden in het bron bestand, gebruik dat in plaats " "van de opgegeven omslag." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "Doel bestands naam. Standaard is gebaseerd op de bron bestandsnaam" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -202,7 +640,7 @@ msgstr "" "Maak HTML tabellen als blokken tekst in plaats van echte tabellen. Dit is " "noodzakelijk als de HTML zeer grote of complexe tabellen bevat." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -212,23 +650,23 @@ msgstr "" "vergroot. Deze optie vervangt de --font-delta optie. Om --fonot-delta te " "gebruiken, zet het op 0. STandaard: %defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "Roteer plaatjes die breder zijn dan het scherm automatisch." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "Zet de spatie ruimte tussen woorden in pts. Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Scheid paragrafen met lege regels." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Voeg een kopregel toe aan alle pagina's met de titel en de auteur." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -236,7 +674,7 @@ msgstr "" "Zet het formaat van de kopregel. %a wordt vervangen door de auteur en %t met " "de titel. Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -244,7 +682,7 @@ msgstr "" "Negeer de CSS. Zit kan of een pad naar een CCS stylesheet zijn, of een " "string. Als het in string is, dan zal deze worden geïnterpreteerd als CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -254,7 +692,7 @@ msgstr "" "waarin de HTML bestanden aan de LRF worden toegevoegd. Het .OPF bestand moet " "zich in dezelfde folder bevinden als het basis HTML bestand." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -262,7 +700,7 @@ msgstr "" "Minimum paragraaf indentatie (De indentatie van de eerste regel in een " "paragraaf) in pts. Standaard: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -272,7 +710,7 @@ msgstr "" "FONT_DELTA pts. FONT_DELTA van een fractie zijn. Als FONT_DELTA negaties is, " "dan zal het lettertype kleiner worden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." @@ -280,7 +718,7 @@ msgstr "" "Geef alle inhoud weer als zwart op wit in plaats van in de kleuren die zijn " "gedefinieerd in de HTML of CSS code." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -290,23 +728,23 @@ msgstr "" "profiel bepaalt zaken zoals de resolutie en scherm grootte van het doel " "apparaat. Standaard: %s Ondersteunde profielen: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Linker kantlijn van pagina. Standaard is %default pixels." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Rechter kantlijn van pagina. Standaard is %default pixels." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Boven marge van pagina. Standaard is %default pixels." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Onder marge van pagina. Standaard is %default pixels." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -314,7 +752,7 @@ msgstr "" "Genereer HTML tabellen als afbeeldingen. (Handig als het document grote of " "gecompliceerde tabellen bevat)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -322,7 +760,7 @@ msgstr "" "Vermenigvuldig de tekst grootte in gegenereerde tabellen bij deze waarde. " "Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -332,7 +770,7 @@ msgstr "" "0 betekent dat de links niet zullen worden gevolgd. Een negatieve waarde " "betekent dat <a> tags worden genegeerd." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -340,15 +778,15 @@ msgstr "" "Een reguliere expressie. <a> tags waar de href mee overeen komt worden " "genegeerd. Standaard: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Voeg geen links toe aan de inhoudsopgave." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Vind niet automatisch nieuwe hoofdstukken." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -356,20 +794,24 @@ msgstr "" "De reguliere expressie die wordt gebruikt om hoofdstukken te herkennen. Deze " "wordt gezocht in 'heading tags' (h1-h6). Standaard: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" -"vind het begin van een hoofdstuk bij een element met het gespecificeerde " -"attribuut. Het formaat voor deze optie is tagnaam regexp, attribuut naam, " -"attribuut waarde regexp. Bijvoorbeeld, om alle kop tags te vinden met de " -"attribuut klasse=\"hoofstuk\", gebruik \"h\\d,klasse,hoofdstuk\". Standaard " +"Herken een hoofdstuk dat begint met een element met het gespecificeerde " +"attribuut. Het formaat voor deze optie is tagname regexp, attribuut naam, " +"attribuut waarde regexp. Bijvoorbeeld: Om alle header tags te vinden met de " +"attribute class=\"chapter\", gebruik \"h\\d,class,chapter\". Je kunt die " +"attribuut als \"none\" opgeven om alleen op tag naam te zoeken. " +"Bijvoorveeld, om alle <h2> tags te vinden, gebruik \"h2,none,\". Standaard " "is %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -388,14 +830,14 @@ msgstr "" "tijd nodig hebben om om te slaan in LRF formaat. Deze optie zal worden " "genegeerd als de huidige pagina weinig elementen bevat." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Forceer een pagina scheiding voor tags wiens naam overeenkomen met deze " "reguliere expressie." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -408,15 +850,15 @@ msgstr "" "class=\"chapter\" te vinden, gebruik: \"h\\d,class,chapter\". Standaard is " "%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Voeg gevonden hoofdstukken toe aan de inhoudsopgave." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "Verwerk Baen HTML bestanden om de gegenereerde RTF te verbeteren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -424,11 +866,11 @@ msgstr "" "Deze optie moet worden toegevoegd indien er bestanden worden verwerkt die " "zijn gegenereerd door pdftohtml, anders zal de conversie falen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Gebruik deze optie met Book Designer html0 bestanden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -441,27 +883,27 @@ msgstr "" "wisselingen. Bijvoorbeeld: --serif-famiy \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "De serif lettertype familie om toe te voegen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "De sand-serif familie om toe te voegen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "De monospace familie om toe te voegen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Geef een uitgebreide omschrijving tijdens het verwerken" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Converteer naar LRS" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -470,7 +912,7 @@ msgstr "" "verwerkingstijd. Gebruik deze optie als je een machine met weinig geheugen " "gebruikt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -483,7 +925,7 @@ msgstr "" "gebruikte keuze is utf-8. Standaard zal er worden geprobeerd om de encoding " "automatisch te herkennen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -500,91 +942,135 @@ msgstr "" "bestanden, en zoekt ebook bestanden in deze archiven.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Geen bestand opgegeven om te converteren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" -msgstr "" +msgstr "Gegenereerd %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "Mislukt %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "" +"Opties voor de configuratie van de conversie van comics (CBR, CBZ) bestanden " +"naar eboek" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" +"Titel voor gegenereerd eboek. Standaard word de bestandsnaam gebruikt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" +"De auteur in de metadata van het gegenereerde eboek. Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" +"Pad naar uitvoer LRF bestand. Standaard zal een bestand worden aangemaakt in " +"de huidige folder." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" +"Aantal kleuren voor beeld conversie naar grijstinten. Standaard: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" +"Geen kleur normalisatie (contrast verbetering) voor afbeeldingen. Standaard: " +"Nee (False)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." -msgstr "" +msgstr "Behoudt afbeelding aspect ratio. Standaard is beeldvullend." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." -msgstr "" +msgstr "Geen aanscherpen." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" -msgstr "" +msgstr "Splits landscape afbeeldingen niet in twee portret afbeeldingen" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Behoudt aspect ratio en schaal afbeelding aan de hand van de schermhoogte " +"als beeld breedte voor het bekijken in landscape modus." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Gebruik voor rechts-naar-links publicaties zoals manga. Hierdoor worden " +"landscape paginas gesplitst in portret paginas van rechts naar links." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" +"Activeer ontspikkelen. Verminderd spikkel ruis. Dit kan de verwerkingstijd " +"flink verlengen." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." msgstr "" +"Sorteer de bestanden in de comic niet alfabetisch op naam - gebruik de " +"voldorde waarin ze zijn toegevoegd aan de comic." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" +"Kies een profiel voor het apparaat waar je een LRF bestand voor maakt. " +"Standaard is de SONY PRS-500 met een scherm grootte van 584x754 pixels. " +"Keuzes zijn %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." msgstr "" +"Uitgebreide informatie, handig voor debuggen. Kan meerdere malen worden " +"opgegeven voor meer informatie." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." -msgstr "" +msgstr "Laat geen vootgangsbalk zien" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" -msgstr "" +msgstr "Uitvoer weggeschreven naar" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Generatie comic bladzijden..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" @@ -598,7 +1084,7 @@ msgstr "" " \n" "%prog converteert mijnbook.epubnaar mijnbook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -610,24 +1096,24 @@ msgstr "" "\n" "%prog converteert mijnbook.fb2 naar mijnbook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Print gegenereerde HTML naar stdout en beëindig." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." msgstr "Bewaar gegenereerde HTML bestanden na conversie naar LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Opties om het gedrag van feeds2disk te beïnvloeden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Opties om het gedrag van html2lrf te beïnvloeden." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Ophalen van recept mislukt: " @@ -655,32 +1141,32 @@ msgstr "Verwerking %s" msgid "\tConverting to BBeB..." msgstr "\tConveteer naar BBEB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Kan bestand niet parseren: %s" -#: /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:537 msgid "%s is an empty file" msgstr "%s is een leeg bestand" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "Link %s %s kan niet worden geparseerd" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "Link %s kan niet worden toegevoegd aan de inhoudsopgave" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "Niet mogelijk om afbeelding %s te verwerken. Foutmelding: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "Niet mogelijk om interlaced PNG bestand %s te verwerken." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" @@ -688,14 +1174,14 @@ msgstr "" "Niet mogelijk om afbeelding %s te verwerken\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" "Een fout is opgetreden tijdens het verwerken van een tabel: %s. Tabel opmaak " "zal worden genegeerd." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" @@ -703,11 +1189,11 @@ msgstr "" "Foutieve tabel:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "Tabel heeft een cel die te groot is." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." @@ -715,19 +1201,19 @@ msgstr "" "De website %s moet eerst als een HTML bestand worden weggeschreven, waarna " "je deze met html2rlf kunt converteren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "Omslag afbeelding kan niet worden ingelezen: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "Kan niet lezen van: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "Verwerking van OPF bestand is niet gelukt." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -745,7 +1231,7 @@ msgstr "" "bestanden wijzen recursief. Het kan dus worden \n" "gebruikt om hele folders in een keer te converteren." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -757,7 +1243,7 @@ msgstr "" "\n" "%prog converteert mijnboek.lit naar mijnboek.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" @@ -765,27 +1251,27 @@ msgstr "" "%prog boek.lrf\n" "Converteer een LRF bestand naar een LRS bestand (XML UTF-8 codering)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "Doel LRS bestand" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "Parsering LRF..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "Creatie XML" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "LRS geschreven naar " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" msgstr "Kan pictogram niet inlezen:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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." @@ -793,16 +1279,16 @@ msgstr "" "%prog [opties] bestand.lrs\n" "Compileer een LRS bestand naar LRF formaat." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" msgstr "Pad naar doel bestand" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "uitgebreide verwerking" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "converteer LRS naar LRF, handig om fouten op te sporen." @@ -825,7 +1311,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "Geef boek titel" @@ -842,7 +1328,7 @@ msgid "Set sort key for the author" msgstr "Geef sorteer sleuter voor de auteur" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "De categorie waarin die boek behoord, bv: Geschiedenis" @@ -891,23 +1377,23 @@ msgstr "" "\n" "%prog converteert mijnboek.mobi naar mijnboek.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "" "Pdftohtml kon niet worden gevonden, controleer of het in je zoekpad zit." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr " staat copieren van tekst niet toe." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" " is een PDF gebaseerd op afbeeldingen. Alleen het converteren van PDF's " "gebaseerd op tekst is ondersteund." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -919,7 +1405,7 @@ msgstr "" "\n" "%prog converteert mijnboek.pdf naar mijnboek.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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." @@ -927,15 +1413,15 @@ msgstr "" "Pad naar output folder waarin het HTML bestand word gemaakt. Standaard is " "dit de huidige folder." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 msgid "Be more verbose." msgstr "Geef meer details." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." msgstr "Specificeer een enkel PDF bestand." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -947,7 +1433,13 @@ msgstr "" "\n" "%prog converteert mijnboek.rtf naar mijnboek.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -959,23 +1451,33 @@ msgstr "" "\n" "%prog converteert mijnboek.txt naar mijnboek.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "Geef de auteur" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "Geef de omschrijving" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" -msgstr "" +msgstr "En lijst tags, gescheiden door komma's" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "Gebruik:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Geen bestandsnaam opgegeven" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -999,23 +1501,23 @@ msgstr "" "gratis account van isbndb.com\n" "\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "Het ISBN ID van het boek dat je de metadata voor wilt." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "De auteur van het boek om naar te zoeken." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "De titel van het boek om naar te zoeken." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "De uitgever van het boek om naar te zoeken." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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." @@ -1023,16 +1525,16 @@ msgstr "" "Omslag kan niet worden gedownload, omdat de server bezig is. Probeer het " "later nog eens." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." msgstr " niet gevonden." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "LibraryThing.com server fout. Probeer het later nog eens." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -1057,97 +1559,224 @@ msgstr "omslag weggeschreven naar" msgid "Usage: pdf-meta file.pdf" msgstr "Gebruik: pdf-meta bestand.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "Geen bestandsnaam opgegeven" +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "%prog [opties] mijnboek.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "RAW MOBI HTML bewaard in" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Vaak gebruikte folders" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "Zend gedownloade periodieke content automatisch naar apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" +"Het formaat te gebruiken voor het wegschrijven van enkele bestanden naar " +"schijf" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Bevestig alvorens verwijdering" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "werkbalk ikoon grootte" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Laat labels zien in de werkbalk" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Hoofdscherm geometrie" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Laat weten wanneer er een nieuwe versie is" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Gebruik Romeinse nummers voor serie nummers" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "Aantal boek covers te laten zien in cover browsing modus" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Standaarden voor conversie naar LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Opties voor de LRF eboek viewer" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Apparaat niet meer verbonden." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Lees apparaat informatie" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Lees boeken lijst van apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Verstuur metadata naar apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "Upload %d boeken naar apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Verwijder boeken van apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Download boeken van apparaat" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Bekijk book op apparaat" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "Titel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "Opmerkingen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Pad" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formaten" + +#: /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/warning_ui.py:52 msgid "Dialog" msgstr "Dialoogvenster" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" msgstr "TekstLabel" +#: /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 "Kies Formaat" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" -msgstr "" +msgstr "Zet standaarden voor conversie van comics (CBR/CBZ bestanden)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" -msgstr "" +msgstr "Zet opties voor conversie %s" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" -msgstr "" +msgstr "&Titel:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" -msgstr "" +msgstr "&Auteur(s)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" -msgstr "" +msgstr "Aantal &Kleuren:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "&Profiel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" -msgstr "" +msgstr "Schakel &normalisatie uit" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" -msgstr "" +msgstr "&Aspectverhouding behouden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" -msgstr "" +msgstr "Schakel ver&scherping uit" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" -msgstr "" +msgstr "&Landscape" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 -msgid "Dont so&rt" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "Niet so&rteren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "&Rechts naar links" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +msgid "De&speckle" +msgstr "Ont&spikkel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "&Wijd" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:23 msgid "Basic" @@ -1157,53 +1786,59 @@ msgstr "Eenvoudig" msgid "Advanced" msgstr "Geavanceerd" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "<br>Moet een folder zijn." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "Foutieve database locatie " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "Foutieve database locatie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Moet een folder zijn." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Foutieve database locatie " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "Foutieve database locatie.<br>Kan niet schrijven naar " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "Database aan het comprimeren. Dit kan even duren." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "Comprimeren..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "Configuratie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" -msgstr "&Locatie van boek database )library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" +msgstr "" +"&Locatie van eboeken. (De eboeken zijn opgeslagen in de folders gesorteerd " +"op auteur, en metadata word bewaard in eht bestand metadata.db)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "Blader naar de nieuwe database locatie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1211,41 +1846,41 @@ msgstr "Blader naar de nieuwe database locatie" #: /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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "Gebruik &Romeinse nummers voor de series" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "&Aantal covers zichtbaar in blader modus (na herstart):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "Notificeer als een &nieuwe versie beschikbaar is" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" -msgstr "" +msgstr "Vraag &bevestiging alvorens bestanden te verwijderen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "Opglagformaat voor &enkel bestand:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "&Prioriteit van conversie batch" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "Standaard netwerk &timeout:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" @@ -1253,59 +1888,76 @@ msgstr "" "Geef de standaard timeout voor netwerk downloads. (bv. wanneer we informatie " "van het Internet moeten halen)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " seconden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "Werkbalk" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "Groot" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "Middel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "Klein" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "&Knop grootte in werkbalk" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "Laat &tekst zien in werkbalk knoppen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "Selecteer zichtbare &kolommen in bibliotheek weergave" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "Vaak gebruikte folders" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "Voeg een folder toe aan de lijst met vaak gebruikte folders" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "Verwijder een folder van de lijst met vaak gebruikte folders" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "Geef ongebruikte diskruimte uit de database terug" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "&Comprimeer database" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "&Metadata van bestands naam" @@ -1313,10 +1965,341 @@ msgstr "&Metadata van bestands naam" msgid "ERROR" msgstr "FOUT" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "Metadata" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "Uiterlijk & gedrag" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "Pagina Instellingen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "Hoofdstuk Detectie" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "stel de detectie van hoofdstuk en sectie koppen in" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "Kies cover voor " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Kan niet lezen" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Je hebt geen permissie om het bestand te lezen: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Fout bij het lezen van bestand" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Er is een fout opgetreden bij het lezen van bestand: <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " is geen geldige afbeelding" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Kan niet converteren" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Geen beschikbare formaten" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" +"Kan %s niet converteren aangezien dit boek geen ondersteunde formaten bevat" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "Boek Omslag" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "Verander &Omslag Afbeelding" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +msgid "Browse for an image to use as the cover of this book." +msgstr "Zoek een afbeelding om als omslag voor dit boek te gebruiken." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "Gebruik omslag van &bron bestand" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "&Titel: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "Verander de titel van dit boek" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "&Auteur(s) " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" +"Verander de auteur(s) van dit boek. Meerdere auteurs moeten met een komma " +"van elkaar worden gescheiden." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "Auteur So&rteer" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "&Uitgeverij " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "Verander de uitgever van dit boek" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "Ta&gs " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" +"Tags bepalen de categorie van het boek. Dit kan handig zijn tijdens het " +"zoeken. <br><br>Ze kunnen woorden of zinsdelen bevatten, gescheiden door " +"komma's." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "&Series:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "Lijst van bekende series. Je kunt nieuwe series toevoegen." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "Series Index." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "Boek " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "Bron &Codering" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "&Linker Kantlijn:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "&Rechter Kantlijn:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "&Boven Marge:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "&Onder Marge:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "Auteur(s)" @@ -1406,35 +2389,6 @@ msgstr "Actieve opdrachten" msgid "&Stop selected job" msgstr "&Stop de geselecteerde opdracht" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "Metadata" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "Uiterlijk & gedrag" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "Pagina Instellingen" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "Hoofdstuk Detectie" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "Geen beschikbare formaten" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" -"Kan %s niet converteren aangezien dit boek geen ondersteunde formaten bevat" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "Kies het formaat om naar LRF te converteren" @@ -1444,33 +2398,10 @@ msgid "Convert %s to LRF" msgstr "Converteer %s naar LRF" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "Zet conversie standaarden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "Kan niet lezen" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "Je hebt geen permissie om het bestand te lezen: " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "Fout bij het lezen van bestand" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "<p>Er is een fout opgetreden bij het lezen van bestand: <br /><b>" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr " is geen geldige afbeelding" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1520,10 +2451,6 @@ msgstr "" "Specificeer de pagina indeling zoals kantlijnen en de scherm grootte van het " "doel aparaat." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "stel de detectie van hoofdstuk en sectie koppen in" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">Help is niet beschikbaar</font>" @@ -1532,283 +2459,158 @@ msgstr "<font color=\"gray\">Help is niet beschikbaar</font>" msgid "Bulk convert ebooks to LRF" msgstr "Converteer meerdere eboeken naar LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "Converteer naar LRF" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "Categorie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "Opties" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "Boek Omslag" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "Verander &Omslag Afbeelding" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "Zoek een afbeelding om als omslag voor dit boek te gebruiken." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "Gebruik omslag van &bron bestand" - -#: /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:263 -msgid "&Title: " -msgstr "&Titel: " - -#: /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:264 -msgid "Change the title of this book" -msgstr "Verander de titel van dit boek" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "&Auteur(s) " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -msgid "" -"Change the author(s) of this book. Multiple authors should be separated by a " -"comma" -msgstr "" -"Verander de auteur(s) van dit boek. Meerdere auteurs moeten met een komma " -"van elkaar worden gescheiden." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "Auteur So&rteer" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "&Uitgeverij " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "Verander de uitgever van dit boek" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "Ta&gs " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -msgid "" -"Tags categorize the book. This is particularly useful while searching. " -"<br><br>They can be any words or phrases, separated by commas." -msgstr "" -"Tags bepalen de categorie van het boek. Dit kan handig zijn tijdens het " -"zoeken. <br><br>Ze kunnen woorden of zinsdelen bevatten, gescheiden door " -"komma's." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "&Series:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "Lijst van bekende series. Je kunt nieuwe series toevoegen." - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "Series Index." - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "Boek " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "Basis &Letter grootte" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr " pts" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" msgstr "Toegevoegde Lettertypen" -#: /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:531 msgid "&Serif:" msgstr "&Serif:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" msgstr "S&ans-serif:" -#: /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:533 msgid "&Monospace:" msgstr "&Monospace:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -msgstr "Bron &Codering" - -#: /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:535 msgid "Minimum &indent:" msgstr "Minimum &indentie:" -#: /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:537 msgid "&Word spacing:" msgstr "&Woord spatiëring" -#: /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:539 msgid "Enable auto &rotation of images" msgstr "Activeer auto &rotatie van afbeeldingen" -#: /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:540 msgid "Insert &blank lines between paragraphs" msgstr "Voeg &blanco regels to tussen paragrafen" -#: /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:541 msgid "Ignore &tables" msgstr "Negeer &tabellen" -#: /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:542 msgid "Ignore &colors" msgstr "Negeer &kleuren" -#: /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:543 msgid "&Preprocess:" msgstr "&Verwerk" -#: /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:544 msgid "Header" msgstr "Koptekst" -#: /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:545 msgid "&Show header" msgstr "Laat koptekst &zien" -#: /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:546 msgid "&Header format:" msgstr "&Koptekst Formaat:" -#: /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:547 msgid "Override<br>CSS" msgstr "Negeer<br>CSS" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -msgstr "&Linker Kantlijn:" - +#: /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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr " px" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "&Rechter Kantlijn:" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "&Boven Marge:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "&Onder Marge:" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" "&Converteer tabellen naar afbeeldingen (Goed voor grote/gecompliceerde " "tabellen)" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "&Multiplier van tekst grootte in gegenereerde tabellen:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "Detectie gebaseerd op Titel" -#: /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:560 msgid "&Disable chapter detection" msgstr "&Deactiveer hoofdstuk detectie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "&Reguliere expressie:" -#: /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:562 msgid "Add &chapters to table of contents" msgstr "Voeg hoofdstukken toe aan de &inhoudsopgave" -#: /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:563 msgid "Don't add &links to the table of contents" msgstr "Voeg geen &links toe aan de inhoudsopgave" -#: /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:564 msgid "Tag based detection" msgstr "Tag-gebaseerde detectie" -#: /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:565 msgid "&Page break before tag:" msgstr "Nieuwe &Pagina voor tag:" -#: /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:566 msgid "&Force page break before tag:" msgstr "&Forceer nieuwe pagina voor tag:" -#: /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:567 msgid "Force page break before &attribute:" msgstr "Forceer nieuwe pagina voor &attribuut:" -#: /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:568 msgid "Detect chapter &at tag:" msgstr "Detecteer hoofdstuk bij t&ag:" -#: /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:569 msgid "Help on item" msgstr "Help voor onderdeel" -#: /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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1818,8 +2620,8 @@ msgstr "" "<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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1829,17 +2631,17 @@ msgid "Edit Meta information" msgstr "Verander Meta informatie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "Meta informatie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "Auteur S&ortering: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." @@ -1848,19 +2650,19 @@ msgstr "" "Bijvoorbeeld: Charles Dickens moet worden gesorteerd als: Dickens, Charles" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "&Rangschikking" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "Rangschikking van dit boek. 0-5 sterren" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr " sterren" @@ -1870,8 +2672,8 @@ msgstr "Voeg Ta&gs Toe: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "Open Tag Editor" @@ -1884,7 +2686,7 @@ msgid "Comma separated list of tags to remove from the books. " msgstr "" "Lijst van tags die moeten worden verwijderd, gescheiden met komma's. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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> " @@ -1894,66 +2696,71 @@ msgstr "" "<br/>Als u deze niet heeft, dan kunt u er gratis een krijgen door te <a " "href='http://www.librarything.com'>registreren</a></p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "<b>Omslag kon niet worden gedownload</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "Omslag kon niet worden gedownload" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "Kan omslag niet downloaden" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "Het ISBN nummer voor dit boek moet worden opgegeven." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "Verander Meta Informatie" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "Wissel auteur en titel van plaats" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "Verwijder ongebruikte series (Series die geen boeken bevatten)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "Download metadata van server" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "Beschikbare Formaten" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "Voeg een nieuw formaat voor dit boek toe aan de database" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "Verwijder de geselecteerde formaten voor dit boek van de database." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "Download omslag afbeelding van de server" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" "Verander de gebruikernaam en/of wachtwoord voor je account met " "LibraryThing.com" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "Wachtwoord wijzigen" @@ -1982,13 +2789,15 @@ msgid "Tag" msgstr "Tag" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "Serie" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "Formaat" @@ -2324,11 +3133,11 @@ msgstr "Regiuliere expressie groep naam (?P<title>)" #: /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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "Geen overeenkomst" @@ -2361,103 +3170,103 @@ msgstr "Reguliere expressie groep naam (?<series_index>)" msgid "ISBN:" msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "Opdracht" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "Status" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "Voortgang" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "Werktijd" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "Fout" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "Onbekende taak" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "Voltooid" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Fout" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" msgstr "Wachten" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "Bezig" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "Opdracht kan niet worden afgebroken" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -"Opdrachten die communiceren met de lezer kunnen niet worden afgebroken omdat " -"dit data corruptie kan veroorzaken." +"Taken die met het apparaat communicaren kunnen niet worden afgebroken" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "Opdrachten die al zijn voltooid kunnen niet worden afgebroken." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "Taak is al uitgevoerd" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "Taak in wachtrij kan niet worden gestopt" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "Geen" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "Tags" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "Formaten" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "Boek <font face=\"serif\">%s</font> van %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "Dubbel-klik om me te <b>wijzigen</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "Grootte (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "Datum" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "Waardering" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "Pad" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "Tijdsaanduiding" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "Zoeken (Voor geavanceerd zoeken klik op de knop links)" @@ -2478,15 +3287,15 @@ msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" "<b>Veranderingen zullen alleen van kracht worden na een herstart.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" msgstr " - LRF Viewer" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "<b>Geen Resultaten</b> voor de zoekterm <i>%s</i> gevonden." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "Geen resultaten gevonden" @@ -2530,11 +3339,11 @@ msgstr "Open eboek" msgid "Configure" msgstr "Configureer" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "Fout bij communicatie met lezer" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" @@ -2542,43 +3351,43 @@ msgstr "" "<p>Voor assistentie, bezoek <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "" "<b>%s</b>: %s door <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "Stuur naar hoofdgeheugen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "Stuur naar opslag kaart" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "en verwijder uit bibliotheek" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "Bewaar standaard op geheugen kaart" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "Bewerk metadata individueel" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "Bewerk metadata in groep" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "Voeg boeken toe uit een enkele folder" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" @@ -2586,7 +3395,7 @@ msgstr "" "Voeg recursief boeken toe (Een boek per folder, neemt aan dat ieder eboek " "bestand hetzelfde boek is in een ander formaat)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" @@ -2594,61 +3403,75 @@ msgstr "" "voeg recursief boeken toe (Meerdere boeken per folder, neemt aan dat ieder " "eboek bestand een ander boek is)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "Opslaan op schijf" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "Opslaan op schijf in een enkele folder" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "Bewaar alleen %s formaat op schijf" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "Bekijk" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "Bekijk specifiek formaat" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "Converteer Individueel" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "Converteer Groep" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" +msgstr "Zet standaarden voor conversie van comics" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr " gedetecteerd" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "Kies een locatie voor de eboek bibliotheek" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "Migratie database" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "Apparaat: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " gedetecteerd" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "Verbonden " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "Apparaat Database Beschadigd" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2677,8 +3500,8 @@ msgstr "" " </ol>\n" " " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" @@ -2686,60 +3509,60 @@ msgstr "" "<p>Boeken met de volgende titels bestaan al in de database. Wil je ze echt " "toevoegen?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "Duplicaten gevonden!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "Boeken worden geupload naar de lezer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "Geen schijfruimte op de lezer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" "<p>De boeken kunnen niet worden geupload naar de lezer, omdat er onvoldoende " "schijfruimte beschikbaar is " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" -msgstr "" +msgstr "Bevesting verwijdering" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" -msgstr "" +msgstr "Weet u zeker dat u deze %d bestanden wilt verwijderen?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "Boeken worden verwijderd van de lezer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "Metedata kan niet worden gewijzigd" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "Geen boeken geselecteerd" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "Boeken worden naar de lezer verzonden." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "Geen geschikte formaten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" @@ -2747,11 +3570,11 @@ msgstr "" "De volgende boeken konden niet naar de lezer worden deupload, omdat geen " "geschikt formaat werd gevonden:<br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "Kan niet naar schijf worden opgeslagen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" @@ -2759,93 +3582,60 @@ msgstr "" "<p>De volgende boeken konden niet worden bewaard op schijf, omdat het %s " "formaat niet beschikbaar is:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "Sommige boeken konden niet worden opgeslagen" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "Download nieuws van " - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "Downloading nieuws van " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "Nieuws gedownload, uploading naar lezer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "Kan niet converteren" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "Begin groep convertering van %d boeken" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "Geen boek geselecteerd" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "Kan niet bekijken" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "Kies het te bekijken formaat" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "%s heeft geen beschikbare formaten" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "Kan niet configureren" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "Can niet configueren terwijl bestaande opdrachten bezig zijn" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "copieer database naar " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "Copieer bibliotheek naar " + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "ongeldige database" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" @@ -2853,23 +3643,23 @@ msgstr "" "<p>Een ongeldige database bestaat op %s, verwijder deze voordat je probeert " "de bestaande database te verplaatsen.<br>Foutmelding: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "Database kon niet worden verplaatst" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "Geen details beschikbaar" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "Geen details zijn beschikbaar voor de boeken op de lezer." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "Fout bij communicatie met lezer" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." @@ -2877,15 +3667,16 @@ msgstr "" "Er is een tijdelijke fout opgetreden tijdens de communicatie met de lezer. " "verwijzer de lezer en plug hem opnieuw in, of herstart." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "Converteer Fout" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "database bestaat niet" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." @@ -2893,7 +3684,11 @@ msgstr "" "De folder waarin de database zou moetten zijn: %s bestaat niet meer. Kies " "een nieuwe database locatie." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "Kies een nieuwe locatie voor de database" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" @@ -2901,7 +3696,7 @@ msgstr "" "<span style=\"color:red; font-weight:bold\">Laatste versie: <a " "href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " @@ -2911,27 +3706,27 @@ msgstr "" "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">nieuwe functies</a> " "Bezoek download pagina?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "Update beschikbaar" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "Calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "Geavanceerde Zoekopdracht" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "&Zoeken:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" @@ -2939,7 +3734,7 @@ msgstr "" "Zoek de boekenlijst op titel of auteur<br><br>Meerdere woorden met spaties " "worden allen gebruikt." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" @@ -2947,60 +3742,68 @@ msgstr "" "Zoek de boekenlijst op titel, auteur, uitgeverij, tags of " "opmerkingen.<br><br>Meerdere woorden met spaties worden allen gebruikt." -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "Snelzoeken wissen" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "Voeg boeken toe" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "A" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "Verwijder boeken" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "Del" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "Wijzig meta informatie" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "E" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "Zend naar lezer" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "Download niews" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "F" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "Converteer E-boeken" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "C" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "V" @@ -3012,7 +3815,7 @@ msgstr "" "Verwijs console output naar een dialoog venster (zowel stdout als stderr). " "Handig onder Windows waar GUI applicatie geen output stream hebben." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "FOUT: Niet-verwerkte uitzondering" @@ -3033,23 +3836,23 @@ msgstr "" msgid "Custom news sources" msgstr "Persoonlijke nieuws bronnen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "Opdrachten" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "Klik om een lijst met actieve opdrachten te zien" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "Klik om boeken bij hun omslag te bekijken" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "Klik om zoeken op omslag uit te schakelen" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" @@ -3057,19 +3860,71 @@ msgstr "" "<p>Bekijken van boeken op omslag is uitgeschakeld.<br>Importeren van " "pictureflow module is mislukt:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "Converteer boek: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "Converteer comic: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Begin groep convertering van %d boeken" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "Converteer boek %d van %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" +"<p>%d van %d boeken kon niet worden geconverteerd, omdat geen schikbaar " +"bron formaat kon worden gevonden:<ul>%s</ul>" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "Sommige boeken konden niet worden geconverteerd" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Download nieuws van " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" msgstr "Ongeldige reguliere expressie" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" msgstr "Ongeldige reguliere expressie: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "Bibliotheek" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" @@ -3077,7 +3932,7 @@ msgstr "" "Lezer\n" "%s beschikbaar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" @@ -3085,38 +3940,42 @@ msgstr "" "Kaart\n" "%s beschikbaar" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "Klik om een de lijst met boeken op uw computer te zien" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "" "Klik om de lijst met boeken in het hoofdgeheugen van uw lezer te zien" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "Klik om de lijst met boeken op de opslag kaart van uw lezer te zien" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" -"Pad naad de Calibre database. Standaard word het pad gebruikt dat is " +"Pad naar de Calibre Bibliotheek. Standaard word het pad gebruikt dat is " "opgeslagen in de instellingen." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "Gebruik bibliotheek uit" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" "%prog list [opties]\n" "\n" -"Laat de boeken zien die beschikbaar zijn in de Calibre database. \n" +"Geef de beschikbare boeken in de Calibre database weer\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -3128,7 +3987,7 @@ msgstr "" "Beschikbare velden: %s\n" "Standaard: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" @@ -3138,11 +3997,11 @@ msgstr "" "Beschikbare velden: %s\n" "Standaard: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "Sorteer resultaten in oplopende volgorde" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 " @@ -3152,15 +4011,15 @@ msgstr "" "kijk naar de zoek-gerelateerde documentatie in de gebruikershandleiding. " "Standaard word er niet gefilterd." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "Ongeldig veld. Beschikbare velden:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "Ongeldig sorteer veld. Beschikbare velden:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" @@ -3168,20 +4027,20 @@ msgstr "" "De volgende boeken zijn niet toegevoegd omdat ze al bestaan in de database. " "(Zie de --duplicates optie):" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" "%prog add [opties] bestand1 bestand2 bestand3 ...\n" "\n" -"Voeg de gespecificeerde bestanden als boeken toe aan de database. Je kunt " -"ook folders opgeven, zie de folder-gerelateerde opties hieronder. \n" +"Voeg de opgegeven bestanden toe als boeken in de database. Folders kunnen " +"ook worden opgegeven, zie de folder gerelateerde opties hier onder.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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" @@ -3190,11 +4049,11 @@ msgstr "" "bestanden in de folder verschillende bestandsformaten zin voor dat enkele " "boek." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "Bewerk folders recursief" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." @@ -3202,11 +4061,11 @@ msgstr "" "Voeg boeken toe aan de database zelfs als deze al bestaan. Vergelijking is " "gebaseerd op de boek titels." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "Ten minste een boek moet worden opgegeven om toe te voegen" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -3220,11 +4079,11 @@ msgstr "" "moeten een lijst zijn die is gescheiden door komma's. (Je kan de id nummers " "zien door het list commando te gebruiken). Bijvoorbeeld, 23,34,57-85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "Ten minste een boek moet worden opgegeven om te verwijderen" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -3239,15 +4098,15 @@ msgstr "" "door het list commando te gebruiken. Als het formaat al bestaat, dan zal het " "worden vervangen.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "zowel een id als een eboek bestand moeten worden gespecificeerd" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "eboek bestand heeft een extensie nodig" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -3264,35 +4123,35 @@ msgstr "" "bestands extensie zoals LRF, TXT of EPUB. Als het logische boek niet in dit " "formaat bestaat, dan zal er niets gebeuren.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "Een id en een formaat moeten worden opgegeven" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" "\n" "%prog show_metadata [opties] id\n" "\n" -"Laat de metadata uit de Calibre database zien voor het boek geidentificeerd " -"met het id. \n" -"id is een id nummer van het list commando \n" +"Geef de metadata weer die is opgeslagen in de Calibre database voor het boek " +"dat word geidentificeerd door id.\n" +"id is een id nummer uit het list commando.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "Print metadata in OPF formaat (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "Je moet een id opgeven" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -3300,85 +4159,138 @@ msgid "" "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" +"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 "" "\n" -"%prog set_metadata [opties] id /pad/naar/metadata.opf\n" +"%prog set_metadata [opties] if /pad/naar/metadata.opf\n" "\n" -"Definieer de metadata die is opgeslagen in de Calibre database voor het " -"boek\n" -"geidenticeerd met id uit het OPF bestand metadata.opf. id is een id nummer " -"uit\n" -"het list commando. Je kunt meer informatie voor het OPF formaat zien door\n" -"--as-opf parameter op te geven bij het show_metadata commando.\n" +"Geef de metadata weer die is opgeslagen in de Calibre database voor het boek " +"dat word geidentificeerd door id ut het OPF bestand metadata.opf. id is een " +"id nummer uit het list commando. Je kunt een kort overzicht voor het OPF " +"formaat krijgen door de -as-opf schakel te gebruiken met het show_metadata " +"commando.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "Je moet een id en metadata bestand opgeven" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" -"%prog export [opties] ids \n" +"%prog export [opties] ids\n" "\n" -"Exporteer de boeken opgegeven als ids (een lijst gescheiden met komma's)\n" -"naar het bestandssysteem. De exporteer operatie bewaard alle formaten van\n" -"het boek, de cover en metadata (in een opf bestand) Je kunt id nummers zien\n" -"via het list commando. \n" +"Exporteer de boeken gespecificeerd door ids (een lijst gescheiden door " +"komma's) naar het bestands systeem.\n" +"De export operatie bewaard alle formaten van het boek, de cover en metadata " +"(in een opf bestand). Je kunt ID nummers verkrijgen door middel van het list " +"commando.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "Exporteer alle boeken in de database, negeer de lijst met ids." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "Exporteer boeken naar de opgegeven folder. Standaard is" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "exporteer alle boeken naar een enkele folder" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "Maak bestands namen als auteur - titel in plaats van titel - auteur" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "Je moet ids opgeven of de %s optie gebruiken" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -"%%prog command [opties] [argumenten]\n" +"%%prof command [opties] [argumenten]\n" "\n" -"%%prog is de commando regel interface voor de Calibre boek database. \n" +"%%prog is de command line interface voor de Calibre boek database.\n" "\n" "commando is een van de volgende:\n" " %s\n" -" \n" -"For help on an individual command: %%prog command --help\n" +"\n" +"Voor help met een specifiek commando: %%prog command --help\n" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "Copieer <b>%s</b>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "<p>Migreer oude database naar eboek bibliotheek in %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "Comprimeren database" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "Werker sessie kan niet worden gestart." +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "Taak gestopt door gebruiker" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sGebruik%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Gemaakt door " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "Pad naar de database waarin boeken zijn opgeslagen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "Patroon om metadata uit bestandsnamen te voorspellen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "Toegangssleutel voor isbndb.com" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "Standaard timeout voor netwerk operaties" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "Pad naar folder waarin je bibliotheek is opgeslagen" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "De fontconfig bibliotheek kon niet worden geinitialiseerd." @@ -3409,7 +4321,149 @@ msgstr "Onbekende feed" msgid "Untitled article" msgstr "Artikel zonder naam" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Timeout in seconden om te wachten op een antwoord van de server. Standaard: " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Minimum inteval in seconden tussen aaneensluitende downloads. Standaard is " +"%default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"De karakter codering voor de websites die je probeert te downloaden. " +"Standaard zal er worden geprobeerd om de codering te raden." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Alleen links die overeenkomen met deze reguliere expressie zullen worden " +"gevolgd. Deze optie kan meerdere keren worden opgegeven, in welk geval de " +"link zal worden gevolgd als deze overeenkomt met ten minste een reguliere " +"expressie. Standaard zullen alle links worden gevolgd." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Iedere link die overeenkomst met deze reguliere expressie zal worden " +"overgeslagen. Deze optie kan meerdere keren worden opgegeven, en als een van " +"de expressies overeenkomst dan zal de link worden genegeerd. Standaard word " +"geen enkele link overgeslagen. indien zowel --filter-regexp en --match-" +"regexp worden gebruikt, dan zal --filter-regexp allereerst worden toegepast." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Download geen CSS stylesheets" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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 "" +"Specificeer een lijst met feeds om te downloaden. Bijvoorbeeld: \n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"Als je deze optie kiest, dan worden andere parameters naar %prog genegeerd " +"en een standaard recept zal worden gebruikt om de feeds te downloaden." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "Geef meer details tijdens het verwerken." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"De titel voor dit recept. Dit word gebruikt als titel voor alle eboeken die " +"worden gemaakt van de gedownloade feeds." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "Gebruikersnaam voor sites die een login vereisen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "Wachtwoord voor sites die een login vereisen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Aantal niveau's dat links gevolgd worden op webpagina's die gelinkt worden " +"door feeds. Standaard: %default" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"De folder waarin de gedownloade feeds worden bewaards. Standaard: de huidige " +"folder." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "Zeer gedetailleerde output, handig met opsporen van problemen." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Handig voor recept ontwikkeling. Forceer max_articles_per_feed als 2 en " +"download niet meer dan 2 feeds." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3448,143 +4502,81 @@ msgstr "" "Beschikbare standaard recepten zijn:\n" "%s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" "Opties om web2disk te besturen (wordt gebruikt om website links in feeds te " "downloaden)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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 "" -"Specificeer een lijst met feeds om te downloaden. Bijvoorbeeld: \n" -"\"['http://feeds.newsweek.com/newsweek/TopNews', " -"'http://feeds.newsweek.com/headlines/politics']\"\n" -"Als je deze optie kiest, dan worden andere parameters naar %prog genegeerd " -"en een standaard recept zal worden gebruikt om de feeds te downloaden." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 -msgid "Be more verbose while processing." -msgstr "Geef meer details tijdens het verwerken." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -msgid "" -"The title for this recipe. Used as the title for any ebooks created from the " -"downloaded feeds." -msgstr "" -"De titel voor dit recept. Dit word gebruikt als titel voor alle eboeken die " -"worden gemaakt van de gedownloade feeds." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:47 -msgid "Username for sites that require a login to access content." -msgstr "Gebruikersnaam voor sites die een login vereisen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "Wachtwoord voor sites die een login vereisen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" -"Aantal niveau's dat links gevolgd worden op webpagina's die gelinkt worden " -"door feeds. Standaard: %default" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "" -"The directory in which to store the downloaded feeds. Defaults to the " -"current directory." -msgstr "" -"De folder waarin de gedownloade feeds worden bewaards. Standaard: de huidige " -"folder." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "Laat geen progressie zien" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "Zeer gedetailleerde output, handig met opsporen van problemen." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -msgid "" -"Useful for recipe development. Forces max_articles_per_feed to 2 and " -"downloads at most 2 feeds." -msgstr "" -"Handig voor recept ontwikkeling. Forceer max_articles_per_feed als 2 en " -"download niet meer dan 2 feeds." - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "Downloading feeds..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "Onbekende Nieuwe Bron" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "Download voltooid" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "De volgende artikelen konden niet worden gedownload:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr " van " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "Delen van de volgende artikelen konden niet worden gedownload:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "\tMislukte links:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" "Artikel kon niet worden gedownload. Draai met --debug om de reden te zien" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "feeds van index pagina" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "Probeer omslag te downloaden" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "Begin download [%d thread(s)]..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "Feeds gedownload tot %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "Kon omslag niet downloaden: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "Download omslag van %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "Artikel zonder Naam" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" @@ -3594,23 +4586,23 @@ msgstr "" "Artikel %s van %s gedownload\n" "%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "Artikel gedownload: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "Artikel %s van %s kon niet worden gedownload\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "Artikel download mislukt: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "Downloading feed" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" @@ -3620,20 +4612,12 @@ msgstr "" "\n" "Waar URL is bijvoorbeeld http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" "basis folder waar de URL naar toe word geschreven. Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Timeout in seconden om te wachten op een antwoord van de server. Standaard: " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3641,7 +4625,7 @@ msgstr "" "Maximum aantal level om recursief te zoeken -- de diepte om links te volgen. " "Standaard %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3649,52 +4633,7 @@ msgstr "" "Het maximum aantal bestanden te downloaden. Dit is alleen van toepassing op " "bestanden in <a href> tags. Standaard is %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Minimum inteval in seconden tussen aaneensluitende downloads. Standaard is " -"%default s" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -msgid "" -"The character encoding for the websites you are trying to download. The " -"default is to try and guess the encoding." -msgstr "" -"De karakter codering voor de websites die je probeert te downloaden. " -"Standaard zal er worden geprobeerd om de codering te raden." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:400 -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 "" -"Alleen links die overeenkomen met deze reguliere expressie zullen worden " -"gevolgd. Deze optie kan meerdere keren worden opgegeven, in welk geval de " -"link zal worden gevolgd als deze overeenkomt met ten minste een reguliere " -"expressie. Standaard zullen alle links worden gevolgd." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 -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 "" -"Iedere link die overeenkomst met deze reguliere expressie zal worden " -"overgeslagen. Deze optie kan meerdere keren worden opgegeven, en als een van " -"de expressies overeenkomst dan zal de link worden genegeerd. Standaard word " -"geen enkele link overgeslagen. indien zowel --filter-regexp en --match-" -"regexp worden gebruikt, dan zal --filter-regexp allereerst worden toegepast." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "Download geen CSS stylesheets" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" "Laat gedetailleerde output informatie zien. Handig bij het opsporen van " diff --git a/src/calibre/translations/pt.po b/src/calibre/translations/pt.po index 770fc2bfd0..cf69ad58b8 100644 --- a/src/calibre/translations/pt.po +++ b/src/calibre/translations/pt.po @@ -7,252 +7,520 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-07-05 03:33+0000\n" "Last-Translator: Tiago Silva <Unknown>\n" "Language-Team: Portuguese <pt@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: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Criado por " - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 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:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 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:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 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:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 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:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 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:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 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:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 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:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 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:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 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:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 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:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -263,12 +531,12 @@ msgid "" "has only a few elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -276,25 +544,25 @@ msgid "" "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 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:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -302,33 +570,33 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 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:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -336,7 +604,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -347,92 +615,114 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -441,7 +731,7 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -449,24 +739,24 @@ msgid "" "%prog converts mybook.fb2 to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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:24 +#: /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:22 +#: /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:24 +#: /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:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "" @@ -494,71 +784,71 @@ msgstr "" msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" 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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -569,7 +859,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -577,48 +867,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -636,7 +926,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "" @@ -653,7 +943,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:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "" @@ -692,20 +982,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -713,21 +1003,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -735,7 +1025,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -743,23 +1039,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -773,38 +1079,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -824,96 +1130,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /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:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -924,53 +1355,57 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -978,99 +1413,116 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1078,10 +1530,335 @@ msgstr "" msgid "ERROR" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "" @@ -1165,34 +1942,6 @@ msgstr "" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "" @@ -1202,33 +1951,10 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1267,10 +1993,6 @@ msgid "" "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "" @@ -1279,276 +2001,156 @@ msgstr "" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "" - -#: /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:264 -msgid "Change the title of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -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/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -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/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" 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:531 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" 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:533 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" 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:539 msgid "Enable auto &rotation of images" msgstr "" -#: /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:540 msgid "Insert &blank lines between paragraphs" 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:541 msgid "Ignore &tables" msgstr "" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" 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:544 msgid "Header" 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:545 msgid "&Show header" 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:546 msgid "&Header format:" 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:547 msgid "Override<br>CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "" -#: /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:560 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" 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:565 msgid "&Page break before tag:" 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:566 msgid "&Force page break before tag:" 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:567 msgid "Force page break before &attribute:" 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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" 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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1559,36 +2161,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 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:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr "" @@ -1598,8 +2200,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1611,71 +2213,76 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "" @@ -1704,13 +2311,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "" @@ -2017,11 +2626,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2054,101 +2663,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2168,15 +2778,15 @@ msgstr "" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "" @@ -2220,118 +2830,132 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 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:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 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:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2347,307 +2971,287 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 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:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 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:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 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:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 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:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 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:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 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:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2657,7 +3261,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2675,78 +3279,132 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2754,68 +3412,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2824,11 +3482,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2837,15 +3495,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2855,29 +3513,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2885,62 +3543,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Criado por " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -2971,7 +3682,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -2992,210 +3817,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 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:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index c3a0b1937e..42546b0ab9 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -6,111 +6,384 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.55\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-07-22 05:50+0000\n" "Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -#, fuzzy -msgid "%sUsage%s: %s\n" -msgstr "%sИспользовано%s: %s\n" +#~ 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\". Default is %default" +#~ msgstr "" +#~ "Определить главу, начинающуюся с элемента, имеющего определенный атрибут. " +#~ "Эта опция должна быть задана в формате: рег. выраж. имени тега,название " +#~ "атрибута,рег. выраж. значения атрибута. Например, для соответствия всем " +#~ "тегами заголовков с атрибутом class=\"chapter\" необходим использовать \"h\\" +#~ "d,class,chapter\". По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "Сделано " - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "Не удалось определить диск %s. Попробуйте перезагрузиться." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "К ридеру не подключена карта памяти." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Неизвестно" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "Укажите заголовок. По умолчанию: имя файла." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 msgid "" "Set the author(s). Multiple authors should be set as a comma separated list. " "Default: %default" msgstr "" -"Укажите автора(ов). Несколько авторов должны быть отделены запятыми. По " -"умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "Неизвестно" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "Укажите комментарий." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 -#, fuzzy -msgid "Set the category" -msgstr "Укажите жанр" - #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +msgid "Set the category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "Значение для сортировки по заголовку" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "Значение для сортировки по автору" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "Издатель" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "Путь к файлу изображения, которое будет использоваться как обложка" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 msgid "" "If there is a cover graphic detected in the source file, use that instead of " "the specified cover." @@ -118,12 +391,12 @@ msgstr "" "Использовать изображение обложки, найденное в исходном файле, вместо " "указанного." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" "Выходное имя файла. По умолчанию будет образовано из имени входного файла" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -131,7 +404,7 @@ msgstr "" "Отображать HTML-таблицы как блоки текста, а не как таблицы. Можно это " "использовать, если HTML содержит слишком большие таблицы." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 " @@ -142,25 +415,25 @@ msgstr "" "над ней. Установите ее в 0, чтобы использовать --font-delta. По умолчанию: " "%default пунктов" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" "Разрешить автоматический разворот изображений, которые не умещаются на " "экране по ширине." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "Укажите отступ между словами в пунктах. По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "Делать пространства между абзацами." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "Добавить верхний колонтитул ко всем страницам с заголовком и автором" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" @@ -168,7 +441,7 @@ msgstr "" "Указать формат верхнего колонтитула. %a будет заменено на автора и %t на " "заголовок. По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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." @@ -176,7 +449,7 @@ msgstr "" "Переопределить CSS. Можно указать путь к файлу стилей CSS или строку. Строка " "будет интерпретирована как CSS-стиль." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 " @@ -186,7 +459,7 @@ msgstr "" "котором HTML-файлы будут следовать в LRF. Файл .opf должен быть в той же " "директории, что и основной HTML-файл." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" @@ -194,7 +467,7 @@ msgstr "" "Минимальный отступ абзаца (отступ первой строки абзаца) в пунктах. По " "умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 " @@ -204,7 +477,7 @@ msgstr "" "FONT_DELTA пунктов. Значение FONT_DELTA может быть дробным. Если FONT_DELTA " "указано отрицательным, то размер шрифта будет уменьшен." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." @@ -212,7 +485,7 @@ msgstr "" "Отображать текст черным цветом на белом фоне, игнорируя цвета, указанные в " "HTML или CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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 " @@ -222,23 +495,23 @@ msgstr "" "определяет такие вещи, как разрешение и размер экрана на целевом устройстве. " "По умолчанию: %s Поддерживаемые профили: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "Отступ слева на странице. По умолчанию: %default пикселей." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "Отступ справа на странице. По умолчанию: %default пикселей." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "Отступ сверху на странице. По умолчанию: %default пикселей." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "Отступ снизу на странице. По умолчанию: %default пикселей." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" @@ -246,7 +519,7 @@ msgstr "" "Представлять таблицы в HTML как изображения (может быть полезным, если в " "документе содержатся большие или сложные таблицы)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" @@ -254,7 +527,7 @@ msgstr "" "Умножить значение размера текста в отображаемых таблицах на это значение. По " "умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 " @@ -264,7 +537,7 @@ msgstr "" "означает, что ссылки не поддерживаются. Отрицательное значение означает, что " "теги <a> будут проигнорированы." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" @@ -272,15 +545,15 @@ msgstr "" "Регулярное выражение. Теги <a>, чьи значения href совпадут с ним, будут " "проигнорированы. По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "Не добавлять ссылок в содержание." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "Отключить автоматическое определение глав." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" @@ -289,20 +562,17 @@ msgstr "" "глав. Иначе будут использованы теги заголовков (h1-h6). По умолчанию: " "%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" -"Определить главу, начинающуюся с элемента, имеющего определенный атрибут. " -"Эта опция должна быть задана в формате: рег. выраж. имени тега,название " -"атрибута,рег. выраж. значения атрибута. Например, для соответствия всем " -"тегами заголовков с атрибутом class=\"chapter\" необходим использовать \"h\\" -"d,class,chapter\". По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -321,14 +591,14 @@ msgstr "" "образом эта опция игнорируется, если определенная страница состоит лишь из " "нескольких элементов." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" "Устанавливать разрывы страниц после тегов, имена которых соответствуют этому " "регулярному выражению." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -336,15 +606,15 @@ msgid "" "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "Добавлять найденные главы в содержание." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "Обработка файлов Baen HTML для улучшения генерируемого LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." @@ -352,11 +622,11 @@ msgstr "" "Вы должны добавить эту опцию, если обрабатываемые файлы были сгенерированы " "утилитой pdftohtml, иначе преобразования не получится." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "Используйте эту опцию для файлов html0 после Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -369,29 +639,27 @@ msgstr "" "страниц. Пример: --serif-family \"Times New Roman\"\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" -msgstr "Набор шрифтов серии \"serif\" для использования" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 -#, fuzzy +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" -msgstr "Набор шрифтов серии \"sans-serif\" для использования" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "Набор шрифтов серии \"monospace\" для использования" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "Отображать избыточную информацию при обработке" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "Преобразовать в LRF" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." @@ -399,7 +667,7 @@ msgstr "" "Уменьшить использование памяти ценой большего времени обработки. Используйте " "эту опцию, если на компьютере ограничена память." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -412,7 +680,7 @@ msgstr "" "распространенный вариант — utf-8. По умолчанию будет сделана попытка угадать " "кодировку." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -431,92 +699,114 @@ msgstr "" "ZIP, пытаясь обнаружить электронную книгу в архиве.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "Не указан файл для преобразования." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -529,7 +819,7 @@ msgstr "" "\n" "%prog преобразует mybook.epub в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -541,24 +831,24 @@ msgstr "" "\n" "%prog преобразует mybook.fb2 в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "Распечатать сгенерированный HTML в stdout и выйти." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /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:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "Опции управления поведением feeds2disk" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of html2lrf" msgstr "Опции управления поведением html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "Скачивание подпорки не удалось: " @@ -575,9 +865,8 @@ msgid "\tBaen file detected. Re-parsing..." msgstr "\tОпределен файл в формате Baen. Повторный разбор..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 -#, fuzzy msgid "Written preprocessed HTML to " -msgstr "Предварительно обработанный HTML сохранен в " +msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 msgid "Processing %s" @@ -587,71 +876,71 @@ msgstr "Обработка %s" msgid "\tConverting to BBeB..." msgstr "\tПреобразование в BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" msgstr "Не удалось разобрать файл: %s" -#: /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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -662,7 +951,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -670,48 +959,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -729,7 +1018,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "" @@ -746,7 +1035,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:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "" @@ -785,20 +1074,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -806,21 +1095,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -828,7 +1117,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -836,23 +1131,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -866,38 +1171,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -917,96 +1222,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /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:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -1017,53 +1447,57 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -1071,99 +1505,116 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1171,10 +1622,335 @@ msgstr "" msgid "ERROR" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "" @@ -1258,34 +2034,6 @@ msgstr "" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "" @@ -1295,33 +2043,10 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1360,10 +2085,6 @@ msgid "" "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "" @@ -1372,276 +2093,156 @@ msgstr "" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "" - -#: /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:264 -msgid "Change the title of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -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/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -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/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" 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:531 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" 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:533 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" 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:539 msgid "Enable auto &rotation of images" msgstr "" -#: /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:540 msgid "Insert &blank lines between paragraphs" 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:541 msgid "Ignore &tables" msgstr "" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" 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:544 msgid "Header" 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:545 msgid "&Show header" 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:546 msgid "&Header format:" 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:547 msgid "Override<br>CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "" -#: /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:560 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" 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:565 msgid "&Page break before tag:" 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:566 msgid "&Force page break before tag:" 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:567 msgid "Force page break before &attribute:" 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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" 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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1652,36 +2253,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 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:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr "" @@ -1691,8 +2292,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1704,71 +2305,76 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "" @@ -1797,13 +2403,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "" @@ -2110,11 +2718,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2147,101 +2755,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2261,15 +2870,15 @@ msgstr "" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "" @@ -2313,118 +2922,132 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 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:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 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:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2440,307 +3063,287 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 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:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 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:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 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:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 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:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 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:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 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:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2750,7 +3353,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2768,78 +3371,132 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2847,68 +3504,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2917,11 +3574,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2930,15 +3587,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2948,29 +3605,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2978,62 +3635,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Сделано " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -3064,7 +3774,135 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Максимальное время ожидания ответа от сервера. По умолчанию: %default с" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Минимальный интервал в секундах между последовательными скачками. По " +"умолчанию: %default с" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Все ссылки, которые соответствуют этому регулярному выражению, будут " +"пропущены. Эту опцию можно указать несколько раз, в этом случае ссылка будет " +"прощена тогда, когда она совпадет хотя бы с одним из регулярных выражений. " +"По умолчанию, никакие ссылки не пропускаются. Если указаны обе опции --" +"filter-regexp и --match-regexp, то вначале будет учитываться --filter-regexp." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Не скачивать файлы стилей CSS." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -3085,169 +3923,113 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" "Каталог, в который будет сохранен файл по URL. По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" -"Максимальное время ожидания ответа от сервера. По умолчанию: %default с" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" @@ -3255,7 +4037,7 @@ msgstr "" "Максимально число уровней рекурсии, т.е. глубина вложенности ссылок. По " "умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" @@ -3263,51 +4045,6 @@ msgstr "" "Максимальное количество файлов для скачивания. Применимо только к файлам из " "тегов <a href>. По умолчанию: %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" -"Минимальный интервал в секундах между последовательными скачками. По " -"умолчанию: %default с" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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 "" -"Все ссылки, которые соответствуют этому регулярному выражению, будут " -"пропущены. Эту опцию можно указать несколько раз, в этом случае ссылка будет " -"прощена тогда, когда она совпадет хотя бы с одним из регулярных выражений. " -"По умолчанию, никакие ссылки не пропускаются. Если указаны обе опции --" -"filter-regexp и --match-regexp, то вначале будет учитываться --filter-regexp." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "Не скачивать файлы стилей CSS." - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "Показывать детальную информацию. Полезно при отладке" diff --git a/src/calibre/translations/sl.po b/src/calibre/translations/sl.po index f82a5d0f7b..137ee12223 100644 --- a/src/calibre/translations/sl.po +++ b/src/calibre/translations/sl.po @@ -6,253 +6,612 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.17\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" -"PO-Revision-Date: 2008-05-24 06:19+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-19 19:17+0000\n" "Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" +#~ msgid "" +#~ "%prog [options] comic.cb[z|r]\n" +#~ "\n" +#~ "Convert a comic in a CBZ or CBR file to an LRF ebook. \n" +#~ msgstr "" +#~ "%prog [options] strip.cb[z|r]\n" +#~ "\n" +#~ "Pretvori strip v CBZ ali CBR datoteki v LRF eknjigo. \n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "" +#~ msgid "Set defaults for conversion to LRF" +#~ msgstr "Nastavi privzeto pretvorbo v LRF" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#~ msgid "Convert comic %d of %d (%s)" +#~ msgstr "Pretvori strip %d od %d (%s)" + +#~ msgid "" +#~ "An XPath expression to detect chapter titles. The default is to consider " +#~ "<h1> or\n" +#~ "<h2> tags that contain the text \"chapter\" or \"book\" or \"section\" as " +#~ "chapter titles. \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 "" +#~ "Xpath izraz za zaznavanje naslova poglavja. Privzeti sta znački <h1> ali\n" +#~ "<h2>, ki ima v naslovu poglavja besede \"chapter\" ali \"book\" ali " +#~ "\"section\". \n" +#~ " Uporabljeni izraz mora določati seznam elementov. Za onemogočanje " +#~ "zaznavanja naslovov \n" +#~ "uporabite izraz \"/\". Za nadaljno pomoč glej XPath Tutorial v Calibre " +#~ "priročniku za uporabo.\n" + +#~ msgid "" +#~ "Maximum number of links from each HTML file to insert into the TOC. Set to 0 " +#~ "to disable. Default is: %default." +#~ msgstr "" +#~ "Maksimalno število povezav iz vsake HTML datoteke, ki se bodo vstavile v " +#~ "Kazalo. Nastavite 0 da oneogočite vstavljanje povezav. Privzeto je: %default." + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." -msgstr "" +msgstr "Zaznava diska v pogonu %s ni mogoča. Poskusite s ponovnim zagonom." -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." +msgstr "Reader nima vstavljene spominske kartice." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "Možnosti za nadzor konverzije v EPUB" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" +"Izhodna datoteka EPUB. Če ni določena, se izpelje iz imena vhodne datoteke." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:61 +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/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "Nadzor samodejnega zaznavanja strukture dokumenta." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "Ne dodaj samodejno zaznanih poglavij v Kazalo." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "Neznano" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "Izbrati morate vhodno HTML datoteko" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "Obdelane HTML datoteke so zapisane v " + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "Možnosti za nadzor sprehajanja po HTML" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "Izhodni direktorij. Privzeti je trenutni direktorij." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" +"Kodna tabela znakov za HTML datoteke. Privzeto je samodejno zaznavanje." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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 "" +"Ustvari izhodne podatke v zip datoteki. Če je izbrana ta možnost mora biti --" +"output ime datoteke, ne direktorija." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:621 +msgid "Control the following of links in HTML files." +msgstr "Nadzira sledeče povezave v HTML datotekah." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" +"Po povezavah v HTML datoteki se sprehodi najprej po širini. Običajno se " +"najprej sprehodi po globini" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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 "" +"Maksimalna stopnja rekurzije pri sledenju povezav v HTML datotekah. Mora " +"biti pozitivna vrednost. 0 pomeni da se ne sledi nobeni povezavi v osnovni " +"HTML datoteki." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:627 +msgid "Set metadata of the generated ebook" +msgstr "Nastavi meta podatke od generirane eknjige" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "Nastavi naslov. Privzeto je samodejno zaznavanje." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "Avtor(ji) eknjige v, z vejicami ločenem, seznamu." + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "Možnosti koristne za razhroščevanje" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "Izhodni HTML je \"lepo oblikovan\" za lažje analiziranje" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" -msgstr "" +msgstr "%prog [options] LITFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." +msgstr "Izhodni direktorij. Privzet je trenutni direktorij." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." -msgstr "" +msgstr "Koristno za razhroščevanje." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 -msgid "Set the title. Default: filename." -msgstr "" +msgstr "OEB eknjiga ustvarjena v" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +msgid "Set the title. Default: filename." +msgstr "Nastavi naslov. Privzeto: filename." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 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:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 -msgid "Set the comment." -msgstr "" +"Nastavi avtorja(je). Več avtorjev se loči z vejicami. Privzeto: %default" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 -msgid "Set the category" -msgstr "" +msgid "Set the comment." +msgstr "Nastavi opombe." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 -msgid "Sort key for the title" -msgstr "" +msgid "Set the category" +msgstr "Nastavi kategorijo" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 -msgid "Sort key for the author" -msgstr "" +msgid "Sort key for the title" +msgstr "Sortirni ključ za kazalo" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 -msgid "Publisher" -msgstr "" +msgid "Sort key for the author" +msgstr "Sortirni ključ za avtorja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 -msgid "Path to file containing image to be used as cover" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 +msgid "Publisher" +msgstr "Založnik" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +msgid "Path to file containing image to be used as cover" +msgstr "Pot do zbirke s sliko, ki se bo uporabila za naslovnico" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 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:91 -msgid "Output file name. Default is derived from input filename" -msgstr "" +"Če je v vhodni zbirki zaznana naslovna stran, jo uporabi namesto izbrane " +"naslovne strani." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +msgid "Output file name. Default is derived from input filename" +msgstr "" +"Ime izhodne datoteke. Privzeta vrednost se izpelje iz vhodne datoteke" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 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 "" +"Upodobi HTML tabele kot tekst. To je potrebno če HTML datoteka vsebuje zelo " +"velike ali kompleksne tabele." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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 "" +"Specificiraj osnovno velikost pisave v pts. Vse pisave so ustrezno " +"skalirane. Ta možnost zastari --font-delta možnost in ima prednost pred njo. " +"Če želite uporabiti --font-delta, nastavite to vrednost na 0. Privzeto: " +"%defaultpt" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 -msgid "Set the space between words in pts. Default is %default" -msgstr "" +msgstr "Omogoči samodejno rotacijo slik, ki so večje od širine zaslona." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 -msgid "Separate paragraphs by blank lines." -msgstr "" +msgid "Set the space between words in pts. Default is %default" +msgstr "Nastavi razmak med besedami v pts. Privzeto je %default" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 -msgid "Add a header to all the pages with title and author." -msgstr "" +msgid "Separate paragraphs by blank lines." +msgstr "Loči odstavke s praznimi vrsticami." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +msgid "Add a header to all the pages with title and author." +msgstr "Dodaj glavo z naslovom in avtorjem na vse strani." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 msgid "" "Set the format of the header. %a is replaced by the author and %t by the " "title. Default is %default" msgstr "" +"Nastavi format glave. %a je zamenjan z avtorjem in %t z naslovom. Privzeto " +"je %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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 "" +"Uporabi <spine> element iz OPF datoteke za določanje vrstnega reda v katerem " +"so HTML datoteke pripete k LRF. Datoteka .opf mora biti v istem direktoriju " +"kot osnovna HTML datoteka." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 msgid "" "Minimum paragraph indent (the indent of the first line of a paragraph) in " "pts. Default: %default" msgstr "" +"Minimalni zamik odstavka (zamik prve vrstice odstavka) v pts. Privzeto: " +"%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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 "" +"Povečaj velikost pisave za 2 * FONT_DELTA pts in razmak med vrsticami za " +"FONT_DELTA pts. FONT_DELTA je lahko decimalno število. Če je FONT_DELTA " +"negativno število se velikost pisave zmanjša." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 msgid "" "Render all content as black on white instead of the colors specified by the " "HTML or CSS." msgstr "" +"Upodobi vso vsebino kot črno na belem namesto z barvami, ki jih določa HTML " +"ali CSS." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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:132 -msgid "Left margin of page. Default is %default px." -msgstr "" +"Profil ciljne naprave za katero se ustvarja ta LRF. Profil določa stvari, " +"kot so resolucija in velikost zaslona ciljne naprave. Privzeto: %s Podprti " +"profili: " #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 -msgid "Right margin of page. Default is %default px." -msgstr "" +msgid "Left margin of page. Default is %default px." +msgstr "Leva meja strani. Privzeto je %default px." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 -msgid "Top margin of page. Default is %default px." -msgstr "" +msgid "Right margin of page. Default is %default px." +msgstr "Desna meja strani. Privzeto je %default px." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 -msgid "Bottom margin of page. Default is %default px." -msgstr "" +msgid "Top margin of page. Default is %default px." +msgstr "Zgornja meja strani. Privzeto je %default px." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +msgid "Bottom margin of page. Default is %default px." +msgstr "Spodnja meja strani. Privzeto je %default px." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 msgid "" "Render tables in the HTML as images (useful if the document has large or " "complex tables)" msgstr "" +"Tabele v HTML datotekah upodobi kot slike (koristno če dokument vsebuje " +"velike ali kompleksne tabele)" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 msgid "" "Multiply the size of text in rendered tables by this factor. Default is " "%default" msgstr "" +"Pomnoži velikost pisave v upodobljenih tabelah s to vrednostjo. Privzeto je " +"%default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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 "" +"Maksimalna globina v katero se obdelujejo povezave. Vrednost 0 pomeni da se " +"povezavam ne sledi. Negativna vrednost pomeni da se <a> značke ne upoštevajo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 msgid "" "A regular expression. <a> tags whose href matches will be ignored. Defaults " "to %default" msgstr "" +"Regularni izraz. <a> značke katerih href se ujema se ne bodo upoštevale. " +"Privzeto na %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." -msgstr "" +msgstr "Ne dodaj povezav v kazalo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." -msgstr "" +msgstr "Onemogoči samodejno zaznavanje poglavij." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 msgid "" "The regular expression used to detect chapter titles. It is searched for in " "heading tags (h1-h6). Defaults to %default" msgstr "" +"Regularni izraz uporabljen za zaznavanje naslovov poglavij. Išče se v " +"oznakah glave (h1-h6). Privzeto je %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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 "" +"Zaznava poglavja, ki se začne z elementom, ki ima specificirane atribute. " +"Format za to možnost je tagname regexp, ime atributa, vrednost atributa " +"regexp. Na primer za izbiro vseh značk glave, ki imajo atribut " +"razred=\"poglavje\" bi uporabili \"h\\d,class,poglavje\". Ta atribut lahko " +"nastavite na \"none\" za ujemanje samo z imeni značk. Naprimer, za ujemanje " +"vseh značk <h2>, bi uporabili \"h2,none,\". Privzeto je %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -262,39 +621,54 @@ msgid "" "turn performance of the LRF. Thus this option is ignored if the current page " "has only a few elements." msgstr "" +"Če html2lrf ne najde prelomov strani v html datoteki in ne more zaznati " +"glave poglavja bo samodejno vstavil prelom strani pred značko, katere ime se " +"ujema s tem regularnim izrazom. Privzeto je %default. To možnost lahko " +"onemogočite tako da nastavite regularni izraz na \"$\". Namen te možnosti je " +"preprečevanje zelo dolgih strani v dokumentu saj to degradira možnost " +"obračanja strani v LRF. Ta možnost se zato ne upošteva, če ima trenutna " +"stran samo nekaj elementov." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" +"Vsili prelom strani pred značkami katerih imena se ujemajo s tem regularnim " +"izrazom." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 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 "" +"Vsili prelom strani pred element, ki ima specificiran atribut. Format za to " +"možnost je tagname regexp,attribute name,attribute value regexp. Naprimer, " +"za ujemanje vseh značk glav, ki imajo atribut class=\"chapter\" bi uporabili " +"\"h\\d,class,chapter\". Privzeto je %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 -msgid "Preprocess Baen HTML files to improve generated LRF." -msgstr "" +msgstr "Dodaj zaznana poglavja v kazalo." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +msgid "Preprocess Baen HTML files to improve generated LRF." +msgstr "Predobdelaj Baen HTML datoteke za izboljšavo ustvarjenih LRF." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 msgid "" "You must add this option if processing files generated by pdftohtml, " "otherwise conversion will fail." msgstr "" +"To možnost morate dodati če obdelujete datoteke ustvarjene s pdftohtml " +"drugače pretvorba nebo uspela." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." -msgstr "" +msgstr "Uporabite to možnost za html0 datoteke iz Book Designer-ja." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -302,41 +676,47 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" -msgstr "" +msgstr "Izbrana pisava iz družine serif" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" -msgstr "" +msgstr "Izbrana pisava iz družine sans-serif" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" -msgstr "" +msgstr "Izbrana pisava iz družine monospace" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 -msgid "Convert to LRS" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +msgid "Convert to LRS" +msgstr "Pretvori v LRS" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 msgid "" "Minimize memory usage at the cost of longer processing times. Use this " "option if you are on a memory constrained machine." msgstr "" +"Minimiziraj porabo pomnilnika kljub daljšem času obdelave. Uporabite to " +"možnost če delate na računalniku z majhnim ali omejenim delovnim pomnilnikom." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 "" +"Določi kodno tabelo izvorne datoteke. Če izhodna LRF datoteka vsebuje čudne " +"znake, poskusite spremeniti to možnost. Pogosta kodna tabela za datoteke iz " +"računalnikov z MS Windows operacijskim sistemom je cp-1252. Druga pogosta " +"kodna tabela je utf-8. Privzeto je ugibanje tipa kodne tabele." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -346,92 +726,135 @@ msgid "" "ZIP archive, looking for an ebook inside the archive.\n" " " msgstr "" +"any2lrf [options] mojaDatoteka\n" +"\n" +"Pretvori knjigo iz poljubnega formata v LRF. Podprti formati so:\n" +"LIT, RTF, TXT, HTML, EPUB, MOBI, PRC in PDF. any2lrf bo obdelal tudi RAR " +"ali\n" +"ZIP arhive in poiskal eknjige znotraj njih.\n" +" " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." -msgstr "" +msgstr "Nobena datoteka ni določena za pretvorbo." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" -msgstr "" +msgstr "Upodobljen %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "Neuspešno %s" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" -msgstr "" +msgstr "Možnosti za nadzor pretvorbe stripov (CBR, CBZ) v eknjige." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." -msgstr "" +msgstr "Naslov ustvarjene eknjige. Privzeta je uporaba imena datoteke." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "" +"Nastavi avtorja v meta podatkih ustvarjene eknjige. Privzeto je %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" +"Pot do izhodne LRF datoteke. Privzeto je da se datoteka ustvari v trenutnem " +"direktoriju." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" +msgstr "Število barv za sivinsko pretvorbo slike. Privzeto: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" +"Onemogoči normalizacijo (izboljšaj kontrast) barvnega razpona za slike. " +"Privzeto: False" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" +"Obdrži razmerje slike. Privzeto je da se prilagodi velikosti zaslona." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." -msgstr "" +msgstr "Onemogoči ostrenje." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" +msgstr "Ne razdeli panoramskih slik v dve portretni" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" +"Obdrži razmerje pri skaliranju slik in uporabi višino zaslona za širino " +"slike pri pregledovanju v panoramskem načinu." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" +"Uporablja se za izdaje, ki se berejo od desne proti levi tako kot manga. " +"Panoramske slike se razdelijo v portretne strani od desne proti levi." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." msgstr "" +"Ne razvrščaj datotek, ki se nahajajo v arhivu stripa po imenu. Upoštevaj " +"vrstni red v katerem so bile dane v strip." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" +"Izberite profil za napravo za katero generirate to LRF datoteko. Privzeta je " +"SONY PRS-500 z velikostjo zaslona 584x754 pikslov. Na izbiro imate %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." -msgstr "" +msgstr "Ne pokaži indikatorja napredka." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" -msgstr "" +msgstr "Izhod se zapiše v" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +msgid "Rendering comic pages..." +msgstr "Upodabljam strani stripa ..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 msgid "" @@ -440,125 +863,140 @@ msgid "" " \n" "%prog converts mybook.epub to mybook.lrf" msgstr "" +"Uporaba: %prog [options] mojaKnjiga.epub\n" +" \n" +" \n" +"%prog pretvori mojaKnjiga.epub v mojaKnjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /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 "" +"%prog [options] mojaKnjiga.fb2\n" +"\n" +"\n" +"%prog pretvori mojaKnjiga.fb2 v mojaKnjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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 "" +msgstr "Izpiši generiran HTML na stdout in se ugasni." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /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 "Obdrži ustvarjene HTML datoteke po uspešni pretvorbi v LRF." + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 +msgid "Options to control the behavior of feeds2disk" +msgstr "Možnosti za nadzor obnašanja feeds2disk" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 -msgid "Options to control the behavior of feeds2disk" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:24 msgid "Options to control the behavior of html2lrf" -msgstr "" +msgstr "Možnosti za nadzor obnašanja html2lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " -msgstr "" +msgstr "Prenos recepta ni uspel: " #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316 msgid "\tBook Designer file detected." -msgstr "" +msgstr "\tBook Designer datoteka zaznana." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 msgid "\tParsing HTML..." -msgstr "" +msgstr "\tParsanje HTML ..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 msgid "\tBaen file detected. Re-parsing..." -msgstr "" +msgstr "\tBaen datoteka zaznana. Ponovno parsanje ..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 msgid "Written preprocessed HTML to " -msgstr "" +msgstr "Preprocesiran HTML zapisan v " #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 msgid "Processing %s" -msgstr "" +msgstr "Procesiranje %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 msgid "\tConverting to BBeB..." -msgstr "" +msgstr "\tPretvarjanje v BBeB ..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" -msgstr "" +msgstr "Parsanje datoteke ni mogoče: %s" -#: /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:537 msgid "%s is an empty file" -msgstr "" +msgstr "%s je prazna datoteka" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" -msgstr "" +msgstr "Neuspešno parsanje povezave %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" -msgstr "" +msgstr "Dodajanje povezave %s v kazalo ni možno" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" -msgstr "" +msgstr "Procesiranje slikovne datoteke %s ni možno. Napaka: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" -msgstr "" +msgstr "Procesiranje interlaced PNG %s ni možno" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" +"Neuspešno procesiranje slike: %s\n" +"%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" +"Prišlo je do napake pri obdelavi tabele: %s. Zgradba tabele se ignorira." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" +"Slaba tabela:\n" +"%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" -msgstr "" +msgstr "Tabela vsebuje preveliko celico" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" +"Spletno stran %s najprej shranite kot html datoteko nato pa na njej " +"uporabite html2lrf." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" -msgstr "" +msgstr "Branje slike naslovne strani ni mogoče: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 -msgid "Failed to process opf file" -msgstr "" +msgstr "Ne morem brati iz: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +msgid "Failed to process opf file" +msgstr "Napaka pri obdelavi opf datoteke" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -568,63 +1006,78 @@ msgid "" "to local files recursively. Thus, you can use it to \n" "convert a whole tree of HTML files." msgstr "" +"Uporaba: %prog [možnosti] mojaKnjiga.html\n" +"\n" +"\n" +"%prog pretvori mojaKnjiga.html v mojaKnjiga.lrf. \n" +"%prog sledi vsem povezavam v mojaKnjiga.html, ki kažejo \n" +"na lokalne datoteke, rekurzivno. Zato ga lahko uporabite za \n" +"pretvorbo celotnega drevesa HTML datotek." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /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 "" +"Uporaba: %prog [možnosti] mojaKnjiga.lit\n" +"\n" +"\n" +"%prog pretvori mojaKnjgia.lit v mojaKnjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" msgstr "" +"%prog knjiga.lrf\n" +"Pretvori LRF datoteko v LRS (XML UTF-8) datoteko" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" -msgstr "" +msgstr "Izhodna LRS datoteka" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." -msgstr "" +msgstr "Parsam LRF ..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." -msgstr "" +msgstr "Ustvarjam XML ..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " -msgstr "" +msgstr "LRS zapisan v " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" -msgstr "" +msgstr "Neuspešen poskus branja iz thumbnail datoteke:" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:263 +#: /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 [možnosti] datoteka.lrs\n" +"Prevedi LRS datoteko v LRF." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" -msgstr "" +msgstr "Pot do izhodne datoteke" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." -msgstr "" +msgstr "Pretvori LRS v LRS, koristno za razhroščevanje." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:455 msgid "Invalid LRF file. Could not set metadata." -msgstr "" +msgstr "Neveljavna LRF datoteka. Nastavljanje meta podatkov ni bilo mogoče." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:580 msgid "" @@ -634,55 +1087,64 @@ msgid "" "Show/edit the metadata in an LRF file.\n" "\n" msgstr "" +"%prog [možnosti] mojaKnjiga.lrf\n" +"\n" +"\n" +"Prikaži/uredi meta podatke v LRF datoteki.\n" +"\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" -msgstr "" +msgstr "Nastavi naslov knjige" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:589 msgid "Set sort key for the title" -msgstr "" +msgstr "Nastavi sortirni ključ za naslov" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:591 msgid "Set the author" -msgstr "" +msgstr "Nastavi avtorja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:593 msgid "Set sort key for the author" -msgstr "" +msgstr "Nastavi sortirni ključ za avtorja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" -msgstr "" +msgstr "Kategorija v katero spada ta knjig. Npr.: Zgodovina" #: /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 "Pot do slike, ki se bo uporabila kot thumbnail za to datoteko" #: /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 "" +"Pot do tekstovne datoteke, ki vsebuje opombe, ki bodo shranjene v lrf " +"datoteki." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:605 msgid "Extract thumbnail from LRF file" -msgstr "" +msgstr "Pridobi thumbnail iz LRF datoteke" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 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 "" +"Pridobi naslovnico iz LRF datoteke. Ker LRF format nima definirane " +"naslovnice, se uporabi nekaj hevristike za ugibanje kaj je naslovnica." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:609 msgid "Set book ID" -msgstr "" +msgstr "Nastavi ID knjige" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 msgid "Don't know what this is for" -msgstr "" +msgstr "Ne vem zakaj je to" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/mobi/convert_from.py:43 msgid "" @@ -691,75 +1153,111 @@ msgid "" "\n" "%prog converts mybook.mobi to mybook.lrf" msgstr "" +"Uporaba: %prog [options] mojaknjiga.mobi|prc\n" +"\n" +"\n" +"%prog pretvori mojaknjiga.mobi v mojaknjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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 "" +msgstr "Ne najdem pdftohtml, preverite če se nahaja v PATH" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." -msgstr "" +msgstr " ne omogoča kopiranje teksta." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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 "" +" je slikovni PDF dokument. Podprta je samo pretvorba tekstovnih PDF " +"dokumentov." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +#: /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 "" +"%prog [options] mojaknjiga.pdf\n" +"\n" +"\n" +"%prog pretvori mojaknjiga.pdf v mojaknjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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 "" +"Pot do izhodnega direktorija v katerem ustvarim HTML datoteko. Privzet je " +"trenutni direktorij." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:404 +#: /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:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 msgid "You must specify a single PDF file." -msgstr "" +msgstr "Izbrati morate samo eno PDF datoteko." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:20 +#: /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 "" +"%prog [options] mojaknjiga.rtf\n" +"\n" +"\n" +"%prog pretvori mojaknjiga.rtf v mojaknjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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 "" +"%prog [options] mojaknjiga.txt\n" +"\n" +"\n" +"%prog pretvori mojaknjiga.txt v mojaknjiga.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" -msgstr "" +msgstr "Nastavi avtorje" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" -msgstr "" +msgstr "Nastavi opombe" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" -msgstr "" +msgstr "Z vejico ločen seznam značk, ki se nastavi" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" -msgstr "" +msgstr "Uporaba:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "Uporaba: imp-meta datoteka.imp" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "Ni izbrane datoteke." + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:96 msgid "" "\n" "%prog [options] key\n" @@ -772,205 +1270,352 @@ msgid "" "isbndb.com.\n" "\n" msgstr "" +"\n" +"%prog [možnosti] ključ\n" +"\n" +"Pridobi meta podatke za knjige iz isndb.com. Določite lahko\n" +"ISBN ID, naslov ali avtorja knjige. Če določite naslov in avtorja\n" +"lahko iskanje najde več kot eno knjigo.\n" +"\n" +"ključ je uporabniški ključ, ki ga generirate ko se prijavite za brezplačen " +"račun na isbndb.com.\n" +"\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." -msgstr "" +msgstr "ISBN ID knjige za katero želite meta podatke." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." -msgstr "" +msgstr "Avtor iskane knjige." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." -msgstr "" +msgstr "Naslov iskane knjige." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." -msgstr "" +msgstr "Založnik iskane knjige." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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 "" +"Prenos naslovne strani ni uspel ker je strežnik preobremenjen. Prosim " +"poskusite kasneje." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 msgid " not found." -msgstr "" +msgstr " ni najden." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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 "" +msgstr "Napaka LibraryThing.com strežnika. Ponovno poskusite kasneje." -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:59 +#: /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 "" +"\n" +"%prog [options] ISBN\n" +"\n" +"Pridobi naslovnico za knjigo, identificirano po ISBN iz LibraryThing.com\n" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:40 msgid "Usage: %s file.lit" -msgstr "" +msgstr "Uporaba: %s datoteka.lit" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:50 msgid "Cover saved to" -msgstr "" +msgstr "Naslovnica shranjena v" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:36 msgid "Usage: pdf-meta file.pdf" -msgstr "" +msgstr "Uporaba: pdf-meta datoteka.pdf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." -msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "Uporaba: rb-meta datoteka.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" -msgstr "" +msgstr "%prog [options] mojaeknjiga.mobi" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" -msgstr "" +msgstr "Neobdelan MOBI HTML shranjen v" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "Pogosto rabljeni direktoriji" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "Samodejno pošlji uspešno prenešeno periodično vsebino napravi." + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "Format, ki se uporablja pri shranjevanju posameznih datotek na disk" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "Potrdite pred brisanjem" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "Velikost ikon v orodni vrstici" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "Prikaži tekstovne oznake v orodni vrstici" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "Geometrija glavnega okna" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "Opozori me kadar je na voljo nova verzija" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "Uporabi rimska števila za številke serij" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "Število naslovnic, ki se pokažejo v cover browsing mode" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "Privzete nastavitve za pretvorbo v LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +msgstr "Možnosti za pregledovalnik LRF eknjig" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "Naprava ni več priklopljena." + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "Pridobi podatke o napravi" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "Pridobi seznam knjig iz naprave" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "Pošlji meta podatke v napravo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +msgid "Upload %d books to device" +msgstr "Prenesi %d knjig v napravo" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "Izbriši knjige iz naprave" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "Prenesi knjige iz naprave" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "Poglej knjigo na napravi" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" -msgstr "" +msgstr "Naslov" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" -msgstr "" +msgstr "Opombe" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +msgid "Path" +msgstr "Pot" + +#: /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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Formats" +msgstr "Formati" + +#: /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/warning_ui.py:52 msgid "Dialog" -msgstr "" +msgstr "Dialog" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" +msgstr "TextLabel" + +#: /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 "" +msgstr "Izberi Format" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" -msgstr "" +msgstr "Nastavi privzete možnosti za pretvorbo stripov (CBR/CBZ datoteke)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" -msgstr "" +msgstr "Nastavi nastavitve za pretvorbo %s" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" -msgstr "" +msgstr "&Naslov:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" -msgstr "" +msgstr "&Avtor(ji):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" -msgstr "" +msgstr "&Število Barv:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" -msgstr "" +msgstr "&Profil:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" -msgstr "" +msgstr "Izklopi &normalizacijo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" -msgstr "" +msgstr "Ohrani r&azmerje" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" -msgstr "" +msgstr "Onemogoči O&strenje" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" -msgstr "" +msgstr "&Panorama" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 -msgid "Dont so&rt" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "Ne &razvrščaj" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "Od desne p&roti levi" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +msgid "De&speckle" +msgstr "De&speckle" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "&Široko" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:23 msgid "Basic" -msgstr "" +msgstr "Osnovno" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:24 msgid "Advanced" -msgstr "" +msgstr "Napredno" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" -msgstr "" +msgstr "Napačna lokacija podatkovne baze" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "<br>Mora biti direktorij." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "Napačna lokacija podatkovne baze " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " -msgstr "" +msgstr "Napačna lokacija podatkovne baze. <br>Ne morem pisati v " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." -msgstr "" +msgstr "Krčenje podatkovne baze. To lahko traja nekaj časa." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." -msgstr "" +msgstr "Krčenje ..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" -msgstr "" +msgstr "Konfiguracija" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" msgstr "" +"&Lokacija eknjig (eKnjige so shranjene v datoteke sortirane po avtorjih, " +"meta podatki pa v datoteki metadata.db)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" -msgstr "" +msgstr "Prebrskaj za novo lokacijo podatkovne baze" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -978,577 +1623,761 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." -msgstr "" +msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" -msgstr "" +msgstr "Uporabi &rimska števila za številke serij" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" +"Število &naslovnic, ki se prikažejo v preletavanju naslovnic (po ponovnem " +"zagonu):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" -msgstr "" +msgstr "Opozori me, ko je na voljo &nova verzija" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" -msgstr "" +msgstr "Vprašaj za &potrditev pred brisanjem datotek." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" -msgstr "" +msgstr "Format za &shranjevanje enojne datoteke:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" -msgstr "" +msgstr "&Prioriteta za pretvorne posle:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" -msgstr "" +msgstr "Privzeti omrežni &timeout:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 -msgid " seconds" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 -msgid "Toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 -msgid "Large" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 -msgid "Medium" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 -msgid "Small" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 -msgid "&Button size in toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 -msgid "Show &text in toolbar buttons" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 -msgid "Select visible &columns in library view" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 -msgid "Add a directory to the frequently used directories list" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 -msgid "Remove a directory from the frequently used directories list" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 -msgid "Free unused diskspace from the database" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 -msgid "&Compact database" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 -msgid "&Metadata from file name" +msgid " seconds" +msgstr " sekund" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 +msgid "Toolbar" +msgstr "Orodna vrstica" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 +msgid "Large" +msgstr "Veliko" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 +msgid "Medium" +msgstr "Srednje" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 +msgid "Small" +msgstr "Majhno" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 +msgid "&Button size in toolbar" +msgstr "Velikost gum&ba orodne vrstice" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 +msgid "Show &text in toolbar buttons" +msgstr "Prikaži &tekst pri gumbih v orodni vrstici" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 +msgid "Select visible &columns in library view" +msgstr "Izberi vidne stolp&ce v knjižničnem pogledu" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 +msgid "Add a directory to the frequently used directories list" +msgstr "Dodaj direktorij k seznamu pogosto rabljenih direktorijev" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 +msgid "Remove a directory from the frequently used directories list" +msgstr "Odstrani direktorij iz seznama pogosto rabljenih direktorijev" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 +msgid "Free unused diskspace from the database" +msgstr "Sprosti neuporabljen prostor iz baze podatkov" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 +msgid "&Compact database" +msgstr "&Skrči podatkovno bazo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 +msgid "&Metadata from file name" +msgstr "&Meta podatki iz imena datoteke" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/conversion_error_ui.py:41 msgid "ERROR" +msgstr "NAPAKA" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 -msgid "Author(s)" -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:31 -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" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 msgid "Metadata" -msgstr "" +msgstr "Meta podatki" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 msgid "Look & Feel" -msgstr "" +msgstr "Izgled & Občutek" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 msgid "Page Setup" -msgstr "" +msgstr "Nastavitve strani" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 msgid "Chapter Detection" -msgstr "" +msgstr "Detekcija Poglavij" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 -msgid "Choose the format to convert into LRF" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:105 -msgid "Convert %s to LRF" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 -msgid "Set conversion defaults" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 msgid "" -"Preprocess the file before converting to LRF. This is useful if you know " -"that the file is from a specific source. Known sources:" +"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." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:256 -msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 msgid "" -"<li><b>pdftohtml</b> - HTML files that are the output of the program " -"pdftohtml</li>" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:258 -msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -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:292 -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:293 -msgid "" -"Specify the page settings like margins and the screen size of the target " -"device." +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 msgid "Fine tune the detection of chapter and section headings." +msgstr "Fino nastavi zaznavanje poglavij in začetkov sekcij." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "Izberi naslovnico za " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "Ne morem prebrati" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "Nimate pravic za branje datoteke: " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "Napaka pri branju zbirke" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "<p>Prišlo je do napake pri branju iz zbirke: <br /><b>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr " ni veljavna slika" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "Pretvorba ni možna" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 -msgid "<font color=\"gray\">No help available</font>" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "Ni razpoložljivih formatov" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "Ne morem pretvoriti %s ker ta knjiga ni na voljo v podprtem formatu" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:404 -msgid "Bulk convert ebooks to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 -msgid "Convert to LRF" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 -msgid "Category" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 -msgid "Options" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 msgid "Book Cover" -msgstr "" +msgstr "Naslovna Stran" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 msgid "Change &cover image:" -msgstr "" +msgstr "Spremeni &sliko naslovne strani:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 msgid "Browse for an image to use as the cover of this book." -msgstr "" +msgstr "Izberi sliko, ki bo uporabljena za naslovnico te knjige." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 msgid "Use cover from &source file" -msgstr "" +msgstr "Uporabi na&slovnico iz izvorne datoteke" -#: /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:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 msgid "&Title: " -msgstr "" +msgstr "&Naslov: " -#: /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:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 msgid "Change the title of this book" -msgstr "" +msgstr "Spremeni naslov knjige" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 msgid "&Author(s): " -msgstr "" +msgstr "&Avtor(ji): " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 msgid "" "Change the author(s) of this book. Multiple authors should be separated by a " "comma" msgstr "" +"Spremeni avtorja(je) te knjige. Če je avtorjev več jih ločite z vejicami." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 msgid "Author So&rt:" -msgstr "" +msgstr "Razv&rščanje Avtorjev:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 msgid "&Publisher: " -msgstr "" +msgstr "&Založnik: " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 msgid "Change the publisher of this book" -msgstr "" +msgstr "Spremeni založnika te knjige" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 msgid "Ta&gs: " -msgstr "" +msgstr "&Značke: " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 #: /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:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 msgid "" "Tags categorize the book. This is particularly useful while searching. " "<br><br>They can be any words or phrases, separated by commas." msgstr "" +"Značke kategorizirajo knjigo. To je uporabno predvsem pri iskanju. " +"<br><br>Lahko so poljubni, z vejicami ločeni, izrazi ali besede." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 #: /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:281 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 msgid "&Series:" -msgstr "" +msgstr "&Serije:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 #: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 msgid "List of known series. You can add new series." -msgstr "" +msgstr "Seznam znanih serij. Lahko dodate nove serije." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 msgid "Series index." -msgstr "" +msgstr "Indeks serij." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 msgid "Book " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 -msgid "Base &font size:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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 -msgid " pts" -msgstr "" +msgstr "Knjiga " +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 -msgid "Embedded Fonts" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 -msgid "&Serif:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 -msgid "S&ans-serif:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 -msgid "&Monospace:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid "Source en&coding:" +msgstr "Kod&na tabela vira:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 -msgid "Minimum &indent:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 -msgid "&Word spacing:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 -msgid "Enable auto &rotation of images" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 -msgid "Insert &blank lines between paragraphs" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 -msgid "Ignore &tables" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 -msgid "Ignore &colors" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 -msgid "&Preprocess:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 -msgid "Header" -msgstr "" - +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 -msgid "&Show header" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 -msgid "&Header format:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 -msgid "Override<br>CSS" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 msgid "&Left Margin:" +msgstr "&Leva Meja:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" 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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 -msgid " px" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 msgid "&Right Margin:" -msgstr "" +msgstr "&Desna Meja:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 msgid "&Top Margin:" -msgstr "" +msgstr "&Zgornja Meja:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 msgid "&Bottom Margin:" +msgstr "&Spodnja Meja:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 -msgid "&Convert tables to images (good for large/complex tables)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 -msgid "&Multiplier for text size in rendered tables:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 -msgid "Title based detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 -msgid "&Disable chapter detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 -msgid "&Regular expression:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 -msgid "Add &chapters to table of contents" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 -msgid "Don't add &links to the table of contents" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 -msgid "Tag based detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 -msgid "&Page break before tag:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 -msgid "&Force page break before tag:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:571 -msgid "Force page break before &attribute:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:572 -msgid "Detect chapter &at tag:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:573 -msgid "Help on item" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:574 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 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:'Candara'; font-size:11pt; 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=\" 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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 +msgid "Author(s)" +msgstr "Avtor(ji)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:38 +msgid "Author Sort" +msgstr "Razvrščanje Avtorjev" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:40 +msgid "ISBN" +msgstr "ISBN" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:104 +msgid "Cannot connect" +msgstr "Ne morem se povezati" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:105 +msgid "You must specify a valid access key for isbndb.com" +msgstr "Vpisati morate veljaven ključ za isbndb.com" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:139 +msgid "Error fetching metadata" +msgstr "Napaka pri prinašanju meta podatkov" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144 +msgid "No metadata found" +msgstr "Ne najdem meta podatkov" + +#: /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 "" +"Ne najdem meta podatkov, poskusite spremeniti naslov, avtorja ali ISBN ključ." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:77 +msgid "Fetch metadata" +msgstr "Prenesi meta podatke" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:78 +msgid "Fetching metadata for <b>%1</b>" +msgstr "Prenašam meta podatke za <b>%1</b>" + +#: /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 "" +"Prijavite se za brezplačen račun na <a " +"href=\"http://www.isbndb.com\">ISBNdb.com</a> in si pridobite dostopni ključ." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:80 +msgid "&Access Key:" +msgstr "&Dostopni Ključ" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:81 +msgid "Fetch" +msgstr "Prenesi" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:82 +msgid "Matches" +msgstr "Zadetki" + +#: /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 "" +"Iz seznama spodaj izberite knjigo, ki se najbolje ujema z vašo kopijo." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:31 +msgid "Details of job" +msgstr "Podrobnosti o poslu" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs.py:27 +msgid "Unavailable" +msgstr "Ni na voljo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs.py:38 +msgid " - Jobs" +msgstr " - Posli" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:38 +msgid "Active Jobs" +msgstr "Aktivni Posli" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:39 +msgid "&Stop selected job" +msgstr "U&stavi izbrani posel" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 +msgid "Choose the format to convert into LRF" +msgstr "Izberite format, ki ga želite pretvoriti v LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:105 +msgid "Convert %s to LRF" +msgstr "Pretvori %s v LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 +msgid "Set conversion defaults" +msgstr "Nastavi privzete možnosti za pretvorbo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 +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 "" +"Predobdelaj datoteko pred pretvorbo v LRF. To je uporabno če je datoteka iz " +"specifičnega vira. Znani viri:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:256 +msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" +msgstr "<ol><li><b>baen</b> - Knjige od založnika BAEN Publishers</li>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:257 +msgid "" +"<li><b>pdftohtml</b> - HTML files that are the output of the program " +"pdftohtml</li>" +msgstr "" +"<li><b>pdftohtml</b> - HTML datoteke, ki so izhod programa pdftohtml</li>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:258 +msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" +msgstr "<li><b>book-designer</b> - HTML0 datoteke iz Book Designer-ja</li>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +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 "" +"Določi meta podatke kot so naslov in avtor knjige.<p>Meta podatki bodo " +"posodobljeni v tako v bazi kot v ustvarjeni LRF datoteki." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "" +"Adjust the look of the generated LRF file by specifying things like font " +"sizes and the spacing between words." +msgstr "" +"Prilagodi izgled ustvarjene LRF datoteke z izbiro stvari kot so velikost " +"pisave in razmak med besedami." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "" +"Specify the page settings like margins and the screen size of the target " +"device." +msgstr "" +"Določi nastavitve strani kot so meje in velikost zaslona ciljne naprave." + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 +msgid "<font color=\"gray\">No help available</font>" +msgstr "<font color=\"gray\">Pomoč ni na voljo</font>" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:404 +msgid "Bulk convert ebooks to LRF" +msgstr "Paketna pretvorba eknjig v LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +msgid "Convert to LRF" +msgstr "Pretvori v LRF" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +msgid "Category" +msgstr "Kategorija" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +msgid "Options" +msgstr "Možnosti" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid "Base &font size:" +msgstr "Osnovna &velikost pisave:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +msgid " pts" +msgstr " pts" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 +msgid "Embedded Fonts" +msgstr "Vgrajene Pisave" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +msgid "&Serif:" +msgstr "&Serif:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 +msgid "S&ans-serif:" +msgstr "S&ans-serif:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 +msgid "&Monospace:" +msgstr "&Monospace:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +msgid "Minimum &indent:" +msgstr "M&inimalni umik vrstice:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +msgid "&Word spacing:" +msgstr "&Razmak med besedami:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +msgid "Enable auto &rotation of images" +msgstr "Omogoči samodejno &rotacijo slik" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +msgid "Insert &blank lines between paragraphs" +msgstr "Vstavi &prazno vrstico med odstavke" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "Ignore &tables" +msgstr "Ignoriraj &tabele" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +msgid "Ignore &colors" +msgstr "Ignoriraj &barve" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Preprocess:" +msgstr "&Predobdelava:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +msgid "Header" +msgstr "Glava" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Show header" +msgstr "&Prikaži glavo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +msgid "&Header format:" +msgstr "&Format glave:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "Override<br>CSS" +msgstr "Ne upoštevaj<br>CSS" + +#: /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:552 +#: /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:556 +msgid " px" +msgstr " px" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +msgid "&Convert tables to images (good for large/complex tables)" +msgstr "&Pretvori tabele v slike (dobro za velike/kompleksne tabele)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +msgid "&Multiplier for text size in rendered tables:" +msgstr "&Množilnik za velikost pisave v upodobljenih tabelah:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +msgid "Title based detection" +msgstr "Zaznavanje po naslovu" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 +msgid "&Disable chapter detection" +msgstr "&Izklopi zaznavanje poglavij" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 +msgid "&Regular expression:" +msgstr "&Regularni izraz:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 +msgid "Add &chapters to table of contents" +msgstr "Dodaj &poglavja v kazalo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +msgid "Don't add &links to the table of contents" +msgstr "Ne dodaj &povezav v kazalo" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 +msgid "Tag based detection" +msgstr "Zaznavanje po značkah" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +msgid "&Page break before tag:" +msgstr "&Prelom strani pred značko:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 +msgid "&Force page break before tag:" +msgstr "&Vsili prelom strani pred značko:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 +msgid "Force page break before &attribute:" +msgstr "Vsili prelom strani pred &atributom:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 +msgid "Detect chapter &at tag:" +msgstr "Zaznaj poglavje &pri znački:" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 +msgid "Help on item" +msgstr "Pomoč za parameter" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 +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; font-" "family:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1556,194 +2385,209 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:114 msgid "Edit Meta information" -msgstr "" +msgstr "Uredi Meta podatke" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" -msgstr "" +msgstr "Meta podatki" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " -msgstr "" +msgstr "&Razvrščanje Avtorjev: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." msgstr "" +"Določi kako se sortirajo avtor(ji) te knige. Naprimer Charles Dickens se " +"sortira kot Dickens, Charles." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" -msgstr "" +msgstr "&Ocena:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" -msgstr "" +msgstr "Ocena za to knjigo. 0-5 zvezdic" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" -msgstr "" +msgstr " zvezdic" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 msgid "Add Ta&gs: " -msgstr "" +msgstr "Dodaj &Značke: " #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" -msgstr "" +msgstr "Odpri Urejevalnik Značk" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 msgid "&Remove tags:" -msgstr "" +msgstr "Odst&rani značke:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 msgid "Comma separated list of tags to remove from the books. " -msgstr "" +msgstr "Z vejico ločen seznam značk, ki bodo odstranjene iz knjig. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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 "" +"<p>Vnesite uporabniško ime in geslo za <b>LibraryThing.com</b>. <br/>Če " +"gesla še nimate se lahko <a " +"href='http://www.librarything.com'>registrirate</a> zastonj!</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" -msgstr "" +msgstr "<b>Prenos naslovnice ni uspel.</b><br/>" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" -msgstr "" +msgstr "Prenos naslovnice ni uspel" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" -msgstr "" +msgstr "Prenos naslovnice ni možen" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." -msgstr "" +msgstr "Določiti morate ISBN oznako te knjige." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" -msgstr "" +msgstr "Uredi Meta Podatke" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" +msgstr "Zamenjaj avtorja in naslov" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 msgid "Remove unused series (Series that have no books)" -msgstr "" +msgstr "Odstrani neuporabljene serije (Serije, ki ne vsebujejo knjig)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" -msgstr "" +msgstr "IS&BN:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" -msgstr "" +msgstr "Prenesi meta podatke iz serverja" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" -msgstr "" +msgstr "Razpoložljivi Formati" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" -msgstr "" +msgstr "Dodaj novi format za to knjigo v podatkovno bazo" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." -msgstr "" +msgstr "Odstrani izbran format za to knjigo iz podatkovne baze." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" -msgstr "" +msgstr "Prenesi sliko naslovne strani s strežnika" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" +"Spremeni uporabniško ime in/ali geslo za vaš račun pri LibraryThing.com" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" -msgstr "" +msgstr "Spremeni geslo" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:55 msgid "Password needed" -msgstr "" +msgstr "Potrebno je geslo" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:57 msgid "&Username:" -msgstr "" +msgstr "&Uporabniško ime:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 msgid "&Password:" -msgstr "" +msgstr "&Geslo:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 msgid "&Show password" -msgstr "" +msgstr "&Prikaži geslo" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:15 msgid "Author" -msgstr "" +msgstr "Avtor" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:17 msgid "Tag" -msgstr "" +msgstr "Značka" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" -msgstr "" +msgstr "Serija" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" -msgstr "" +msgstr "Format" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:21 msgid "Any" -msgstr "" +msgstr "Vsak" #: /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 "" +msgstr "Forma" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:36 msgid "contains" -msgstr "" +msgstr "vsebuje" #: /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 "" +msgstr "Tekst ki ga iščete. Interpretira se kot regularni izraz." #: /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 "" +"<p>Negiraj zadetke. Vrnjeni bodo samo zadetki ki se <b>ne ujemajo</b> z " +"iskalnim nizom." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:39 msgid "Negate" -msgstr "" +msgstr "Negiraj" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:73 msgid "Advanced Search" -msgstr "" +msgstr "Napredno iskanje" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:74 msgid "Match a&ll of the following criteria" @@ -1755,156 +2599,160 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:76 msgid "Search criteria" -msgstr "" +msgstr "Iskalni kriterij" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:77 msgid "More" -msgstr "" +msgstr "Več" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:78 msgid "Fewer" -msgstr "" +msgstr "Manj" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:123 msgid "Tag Editor" -msgstr "" +msgstr "Urejevalnik Značk" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:124 msgid "A&vailable tags" -msgstr "" +msgstr "Razpoložlji&ve značke" #: /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 "" +"Izbriši značko iz podatkovne baze. To bo odstranilo značko iz vseh knjig, ki " +"jo imajo in jo izbrisalo iz podatkovne baze." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:127 msgid "Apply tag to current book" -msgstr "" +msgstr "Dodaj značko trenutni knjigi" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:129 msgid "A&pplied tags" -msgstr "" +msgstr "&Dodane značke" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:130 msgid "Unapply (remove) tag from current book" -msgstr "" +msgstr "Odvzami značko trenutni knjigi" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:132 msgid "&Add tag:" -msgstr "" +msgstr "&Dodaj značko:" #: /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 "" +"Če značka, ki jo želite ni na voljo jo lahko dodate tukaj. Sprejme z " +"vejicami ločen seznam značk." #: /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 "" +msgstr "Dodaj značko k trenutni knjigi in značkam, ki so na voljo" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:63 msgid "No recipe selected" -msgstr "" +msgstr "Noben recept ni izbran." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 msgid "The attached file: %s is a recipe to download %s." -msgstr "" +msgstr "Pripeta datoteka: %s je recept za prenos %s." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 msgid "Recipe for " -msgstr "" +msgstr "Recept za " #: /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:214 msgid "Switch to Advanced mode" -msgstr "" +msgstr "Preklopi v Napredni način" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:100 msgid "Switch to Basic mode" -msgstr "" +msgstr "Preklopi v Osnovni način" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 msgid "Feed must have a title" -msgstr "" +msgstr "Feed mora imeti naslov" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:111 msgid "The feed must have a title" -msgstr "" +msgstr "Feed mora imeti naslov" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 msgid "Feed must have a URL" -msgstr "" +msgstr "Feed mora imeti URL" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:116 msgid "The feed %s must have a URL" -msgstr "" +msgstr "Feed %s mora imeti URL" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 msgid "Already exists" -msgstr "" +msgstr "Že obstaja" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:122 msgid "This feed has already been added to the recipe" -msgstr "" +msgstr "Ta feed je že bil dodan v recept" #: /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:195 msgid "Invalid input" -msgstr "" +msgstr "Nepravilen vnos" #: /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:196 msgid "<p>Could not create recipe. Error:<br>%s" -msgstr "" +msgstr "<p>Kreiranje recepta ni bilo mogoče. Napaka:<br>%s" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 msgid "Replace recipe?" -msgstr "" +msgstr "Zamenjam recept?" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:202 msgid "A custom recipe named %s already exists. Do you want to replace it?" -msgstr "" +msgstr "Vir novic po meri z imenom %s že obstaja. Ga želite zamenjati?" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:188 msgid "Choose a recipe file" -msgstr "" +msgstr "Izberite recept" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:188 msgid "Recipes" -msgstr "" +msgstr "Recepti" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:208 msgid "Add custom news source" -msgstr "" +msgstr "Dodaj vir novic po meri" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:209 msgid "Available user recipes" -msgstr "" +msgstr "Recepti uporabnika, ki so na voljo" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:210 msgid "Add/Update &recipe" -msgstr "" +msgstr "Dodaj/Posodobi &recept" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:211 msgid "&Remove recipe" -msgstr "" +msgstr "Odst&rani recept" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:212 msgid "&Share recipe" -msgstr "" +msgstr "&Deli recept" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:213 msgid "&Load recipe from file" -msgstr "" +msgstr "Na&loži recept iz datoteke" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 msgid "" @@ -1922,62 +2770,65 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:219 msgid "Recipe &title:" -msgstr "" +msgstr "Naslov recep&ta:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:220 msgid "&Oldest article:" -msgstr "" +msgstr "&Najstarejši članek:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:221 msgid "The oldest article to download" -msgstr "" +msgstr "Najstarejši članek, ki je na voljo za prenos" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:222 msgid " days" -msgstr "" +msgstr " dni" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:223 msgid "&Max. number of articles per feed:" -msgstr "" +msgstr "&Maks. število člankov na feed:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:224 msgid "Maximum number of articles to download per feed." -msgstr "" +msgstr "Maksimalno število člankov, ki se prenesejo iz enega feed-a." #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:225 msgid "Feeds in recipe" -msgstr "" +msgstr "Feed-i v receptu" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:227 msgid "Remove feed from recipe" -msgstr "" +msgstr "Odstrani feed iz recepta" #: /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:233 msgid "Add feed to recipe" -msgstr "" +msgstr "Dodaj feed receptu" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:231 msgid "&Feed title:" -msgstr "" +msgstr "Naslov &feed-a:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:232 msgid "Feed &URL:" -msgstr "" +msgstr "Feed &URL:" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:234 msgid "&Add feed" -msgstr "" +msgstr "Dod&aj feed" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:235 msgid "" "For help with writing advanced news recipes, please visit <a " "href=\"http://calibre.kovidgoyal.net/user_manual/news.html\">User Recipes</a>" msgstr "" +"Za pomoč pri pisanju naprednih receptov za pridobivanje novic prosim " +"obiščite <a " +"href=\"http://calibre.kovidgoyal.net/user_manual/news.html\">User Recipes</a>" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:236 msgid "Recipe source code (python)" -msgstr "" +msgstr "Izvorna koda recepta (python)" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 msgid "" @@ -1987,26 +2838,31 @@ msgid "" "available.<p>Use the <b>Test</b> functionality below to test your regular " "expression on a few sample filenames." msgstr "" +"<p>Nastavi regularni izraz, ki se uporabi pri ugibanju meta podatkov od " +"knjige iz datotek. <p>A <a href=\"http://docs.python.org/lib/re-" +"syntax.html\">Referenca</a> o sintaksi regularnih izrazov je na " +"voljo.<p>Uporabite <b>Test</b> funkcionalnost spodaj za testiranje lastnih " +"regularnih izrazov na nekaj vzorčnih imenih datotek." #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:98 msgid "Regular &expression" -msgstr "" +msgstr "R&egularni izraz" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:99 msgid "&Test" -msgstr "" +msgstr "&Test" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:100 msgid "File &name:" -msgstr "" +msgstr "&Ime datoteke:" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:101 msgid "Test" -msgstr "" +msgstr "Test" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:102 msgid "Title:" -msgstr "" +msgstr "Naslov:" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:103 msgid "Regular expression group name (?P<title>)" @@ -2017,17 +2873,17 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" +msgstr "Brez zadetka" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:105 msgid "Authors:" -msgstr "" +msgstr "Avtorji:" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 msgid "Regular expression group name (?P<authors>)" @@ -2035,7 +2891,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 msgid "Series:" -msgstr "" +msgstr "Serije:" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 msgid "Regular expression group name (?P<series>)" @@ -2043,7 +2899,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 msgid "Series index:" -msgstr "" +msgstr "Indeks serij:" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 @@ -2052,286 +2908,307 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 msgid "ISBN:" -msgstr "" +msgstr "ISBN:" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" -msgstr "" +msgstr "Posel" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" -msgstr "" +msgstr "Status" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" -msgstr "" +msgstr "Napredek" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" -msgstr "" +msgstr "Čas izvajanja" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "Neznan posel" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" -msgstr "" +msgstr "Končano" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "Napaka" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 msgid "Waiting" -msgstr "" +msgstr "Čakam" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" -msgstr "" +msgstr "Delam" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" -msgstr "" +msgstr "Prekinitev posla ni mogoča" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "Ne morem prekiniti poslov, ki komunicirajo z napravo" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "Posel je že bil pognan" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 -msgid "None" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "Ne morem prekiniti čakajočih poslov" +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 +msgid "None" +msgstr "Nič" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" -msgstr "" +msgstr "Značke" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." -msgstr "" +msgstr "Knjiga <font face=\"serif\">%s</font> od %s." -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" -msgstr "" +msgstr "Dvoklikni me da me <b>urediš</b><br><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" -msgstr "" +msgstr "Velikost (MB)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" -msgstr "" +msgstr "Datum" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" -msgstr "" +msgstr "Ocena" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" -msgstr "" +msgstr "Časovna znamka" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" -msgstr "" +msgstr "Najdi (Za Napredno Iskanje pritisnite gumb na levi)" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:47 msgid "Configure Viewer" -msgstr "" +msgstr "Nastavi Pregledovalnik" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:48 msgid "Use white background" -msgstr "" +msgstr "Uporabi belo ozadje" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:49 msgid "Hyphenate" -msgstr "" +msgstr "Veži z vezajem" #: /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 "" +msgstr "<b>Spremembe se upoštevajo po ponovnem zagonu.</b>" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 msgid " - LRF Viewer" -msgstr "" +msgstr " - LRF Pregledovalnik" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /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 "" +msgstr "<b>Ni zadetkov</b> za iskalni niz <i>%s</i>." -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" -msgstr "" +msgstr "Nič zadetkov najdenih" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:128 msgid "LRF Viewer" -msgstr "" +msgstr "LRF Pregledovalnik" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:129 msgid "Parsing LRF file" -msgstr "" +msgstr "Parsanje LRF datoteke" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:130 msgid "LRF Viewer toolbar" -msgstr "" +msgstr "Orodna vrstica LRF Pregledovalnika" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:131 msgid "Next Page" -msgstr "" +msgstr "Naslednja Stran" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:132 msgid "Previous Page" -msgstr "" +msgstr "Prejšnja Stran" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:133 msgid "Back" -msgstr "" +msgstr "Nazaj" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:134 msgid "Forward" -msgstr "" +msgstr "Naprej" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:135 msgid "Next match" -msgstr "" +msgstr "Naslednji zadetek" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:136 msgid "Open ebook" -msgstr "" +msgstr "Odpri eknjigo" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:137 msgid "Configure" -msgstr "" +msgstr "Nastavi" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" -msgstr "" +msgstr "Napaka pri komuniciranju z napravo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" msgstr "" +"<p>Za pomoč obiščite <a " +"href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -msgstr "" +msgstr "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" -msgstr "" +msgstr "Pošlji v glavni pomnilnik" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 -msgid "and delete from library" -msgstr "" +msgstr "Pošlji v spominsko kartico" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "and delete from library" +msgstr "in izbriši iz knjižnice" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 -msgid "Edit metadata individually" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 -msgid "Edit metadata in bulk" -msgstr "" +msgstr "Privzeto pošlji v spominsko kartico" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 -msgid "Add books from a single directory" -msgstr "" +msgid "Edit metadata individually" +msgstr "Posamično urejanje meta podatkov" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +msgid "Edit metadata in bulk" +msgstr "Paketno urejanje meta podatkov" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 +msgid "Add books from a single directory" +msgstr "Dodaj knjige iz enega direktorija" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" msgstr "" +"Dodaj knjige rekurzivno (Ena knjiga na direktorij, privzame da je vsaka " +"datoteka ista eknjiga v različnih formatih)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" +"Dodaj knjige rekurzivno (Več knjig na direktorij, privzame da je vsaka " +"datoteka različna knjiga)" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 -msgid "Save to disk in a single directory" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 -msgid "Save only %s format to disk" -msgstr "" +msgstr "Shrani na disk" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 -msgid "View" -msgstr "" +msgid "Save to disk in a single directory" +msgstr "Shrani na disk v en direktorij" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +msgid "Save only %s format to disk" +msgstr "Shrani samo %s format na disk" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 +msgid "View" +msgstr "Poglej" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 -msgid "Convert individually" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 -msgid "Bulk convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" -msgstr "" +msgstr "Poglej specifičen format" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +msgid "Convert individually" +msgstr "Posamična pretvorba" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +msgid "Bulk convert" +msgstr "Paketna pretvorba" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" +msgstr "Nastavi privzete možnosti za pretvorbo stripov" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "Izberite lokacijo za vašo eKnjižnico." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "Selitev podatkovne baze" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " -msgstr "" +msgstr "Naprava: " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr " zaznan." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " -msgstr "" +msgstr "Povezan " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" -msgstr "" +msgstr "Podatkovna baza poškodovana" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2346,476 +3223,585 @@ msgid "" " </ol>\n" " " msgstr "" +"\n" +" <p>Podatkovna baza knjig na reader-ju je poškodovana. " +"Poskusite sledeče:\n" +" <ol>\n" +" <li>Izklopite reader iz računalnika. Počakajte da konča s " +"ponovnim generiranjem baze (npr. počakajte dokler ni pripravljen za " +"uporabo). Vklopite reader nazaj v računalnik. Sedaj bi moral delovati z " +"%(app). Če ne deluje poskusite naslednji korak.</li>\n" +" <li>Končajte %(app). Poiščite datoteko media.xml v glavnem " +"spominu reader-ja. Izbrišite jo in izklopite reader iz računalnika. " +"Počakajte da datoteko ponovno ustvari. Ponovno priklopite reader in zaženite " +"%(app).</li>\n" +" </ol>\n" +" " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" msgstr "" +"<p>Knjige z istim naslovom že obstajajo v bazi. Jih vseeno dodam?<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" -msgstr "" +msgstr "Duplikati najdeni!" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." -msgstr "" +msgstr "Prenašanje knjig na napravo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" -msgstr "" +msgstr "Na napravi ni več prostora" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" +"<p>Prenos knjig na napravo ni mogoč, ker na napravi ni dovolj prostora " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" -msgstr "" +msgstr "Potrdite brisanje" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" -msgstr "" +msgstr "Ali ste prepričani da želite izbrisati teh %d knjig?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." -msgstr "" +msgstr "Izbriši knjige iz naprave." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" -msgstr "" +msgstr "Spreminjanje meta podatkov ni mogoče" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" -msgstr "" +msgstr "Nobena od knjig ni izbrana." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." -msgstr "" +msgstr "Pošlji knjige v napravo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" -msgstr "" +msgstr "Ni ustreznih formatov" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" msgstr "" +"Prenos sledečih knjig ni uspel, ker ni bil najden potreben " +"format:<br><ul>%s</ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" -msgstr "" +msgstr "Ne morem shraniti na disk" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" msgstr "" +"<p>Prenos sledečih knjig na disk ni uspek, ker %s format ni na voljo " +"zanje:<ul>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" -msgstr "" +msgstr "Nekaterih knjig ni bilo mogoče shraniti" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " -msgstr "" +msgstr "Prenašam novice iz " -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." -msgstr "" +msgstr "Novice prenešene. Pošiljam napravi." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" -msgstr "" +msgstr "Nobena od knjig ni izbrana" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" +msgstr "Pogled ni možen" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 +msgid "Choose the format to view" +msgstr "Izberite format, ki ga želite videti" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 +msgid "%s has no available formats." +msgstr "%s nima razpoložljivih formatov." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure" +msgstr "Nemogoča konfiguracija" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure while there are running jobs." +msgstr "Spreminjanje konfiguracije med poganjanjem poslov ni mogoče." + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 -msgid "Choose the format to view" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "Kopiram knjižnico v " #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 -msgid "%s has no available formats." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 -msgid "Cannot configure" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 -msgid "Cannot configure while there are running jobs." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 msgid "Invalid database" -msgstr "" +msgstr "Neustrezna podatkovna baza" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" msgstr "" +"<p>Neveljavna podatkovna baza že obstaja v %s, izbrišite jo preden poskusite " +"premakniti obstoječo podatkovno bazo.<br>Napaka: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" -msgstr "" +msgstr "Premik podatkovne baze ni bil mogoč" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" -msgstr "" +msgstr "Podrobne informacije niso na voljo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." -msgstr "" +msgstr "Podrobne informacije za knjige na napravi niso na voljo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" -msgstr "" +msgstr "Napaka pri pogovoru z napravo" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." msgstr "" +"Prišlo je do napake pri komuniciranju z napravo. Prosim ponovno zaženite ali " +"izklopite in ponovno vklopite napravo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" -msgstr "" +msgstr "Pretvorna Napaka" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" -msgstr "" +msgstr "Podatkovna baza ne obstaja" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." msgstr "" +"Direktorij v katerem naj bi bila podatkovna baza: %s ne obstaja več. Prosim " +"izberite novo lokacijo." -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "Izberite novo lokacijo za podatkovno bazo" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" msgstr "" +"<span style=\"color:red; font-weight:bold\">Zadnja verzija: <a " +"href=\"%s\">%s</a></span>" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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 "" +"%s je bil nadgrajen na verzijo %s. Poglejte <a " +"href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">seznam " +"posodobitev</a>. Prikažem domačo stran?" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" -msgstr "" +msgstr "Navoljo je posodobitev" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" -msgstr "" +msgstr "calibre" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" -msgstr "" +msgstr "Napredno iskanje" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" -msgstr "" +msgstr "Alt+S" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" -msgstr "" +msgstr "I&skanje:" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" msgstr "" +"Iskanje knjig po naslovu ali avtorju<br><br>Besede ločene s presledkom se " +"obravnavajo po pravilu IN" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 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:263 -msgid "Reset Quick Search" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 -msgid "Add books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 -msgid "A" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 -msgid "Remove books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 -msgid "Del" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 -msgid "Edit meta information" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 -msgid "E" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 -msgid "Send to device" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 -msgid "S" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 -msgid "Fetch news" -msgstr "" +"Iskanje knjig po naslovu, avtorju, založniku, značkah ali " +"opombah<br><br>Besede ločene s presledkom se obravnavajo po pravilu IN" #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 -msgid "F" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 -msgid "Convert E-books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 -msgid "C" -msgstr "" +msgid "Reset Quick Search" +msgstr "Resetiraj Hitro Iskanje" #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 -msgid "V" +msgid "Match any" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 +msgid "Add books" +msgstr "Dodaj knjige" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 +msgid "A" +msgstr "A" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 +msgid "Remove books" +msgstr "Odstrani knjige" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 +msgid "Del" +msgstr "Del" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 +msgid "Edit meta information" +msgstr "Uredi meta podatke" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 +msgid "E" +msgstr "E" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 +msgid "Send to device" +msgstr "Pošlji napravi" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 +msgid "S" +msgstr "S" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 +msgid "Fetch news" +msgstr "Prenesi novice" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 +msgid "F" +msgstr "F" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 +msgid "Convert E-books" +msgstr "Pretvori eKnjige" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 +msgid "C" +msgstr "C" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 +msgid "V" +msgstr "V" + #: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:17 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 "" +"Preusmeri konzolne izhodne podatke v okno (stdout in stderr). Koristno za " +"windows ker v njem GUI aplikacije nimajo izhodnih nizov." -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" -msgstr "" +msgstr "NAPAKA: Neobdelana izjema" #: /home/kovid/work/calibre/src/calibre/gui2/news.py:32 msgid "Add a custom news source" -msgstr "" +msgstr "Dodaj vir novic po meri" #: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 msgid "" "<p>Please enter your username and password for %s<br>If you do not have one, " "please subscribe to get access to the articles.<br/> Click OK to proceed." msgstr "" +"<p>Vstavite uporabniško ime in geslo za %s<br>V kolikor ga še nimate se " +"prijavite, da dobite dostop do člankov.<br/> Pritisnite OK za nadaljevanje." #: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 msgid "Custom news sources" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 -msgid "Jobs:" -msgstr "" +msgstr "Viri novic po meri" #: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +msgid "Jobs:" +msgstr "Posli:" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." -msgstr "" +msgstr "Klikni za seznam aktivnih poslov." -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" -msgstr "" +msgstr "Kliknite za izbiranje knjig po platnici." -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" -msgstr "" +msgstr "Pritisnite za izklop Preletavanja Platnic" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" +"<p>Izbiranje knjig po platnici je onemogočeno.<br>Uvoz pictureflow modula ni " +"uspel:<br>" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "Pretvori knjigo: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "Pretvori strip: " + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "Začenjam Paketno pretvarjanje %d knjig" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "Pretvori knjigo %d od %d (%s)" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" +"<p>Pretvorba %d od %d ni uspela, ker zanje ni bil najden potreben izvorni " +"format.<ul>%s</ul>" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "Pretvorba nekaterih knjig ni bila možna" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +msgstr "Prenesi novice iz " + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 msgid "Invalid regular expression" -msgstr "" +msgstr "Neveljaven regularni izraz" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 msgid "Invalid regular expression: %s" -msgstr "" +msgstr "Neveljaven regularni izraz: %s" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" -msgstr "" +msgstr "Knjižnica" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" +"Reader\n" +"%s je na voljo" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" +"Kartica\n" +"%s je na voljo" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" -msgstr "" +msgstr "Kliknite za seznam knjig, ki so na voljo na vašem računalniku" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 msgid "Click to see the list of books in the main memory of your reader" msgstr "" +"Kliknite za seznam knjig, ki so na voljo v glavnem pomnilniku vašega reader-" +"ja" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" +"Kliknite za seznam knjig, ki so na voljo v spominski kartici v vašem reader-" +"ju" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"Path to the calibre library. Default is to use the path stored in the " "settings." msgstr "" +"Pot do calibre knjižnice. Privzeta je pot, ki je shranjena v nastavitvah." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "Uporabljam knjižnico v" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" +"%prog list [možnosti]\n" +"\n" +"Izpiše knjige ki so na voljo v podatkovni bazi od calibre.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 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" msgstr "" +"Polja, ki se prikažejo pri prikazovanju knjig iz baze. Mora biti z vejico " +"ločen seznam polj.\n" +"Polja, ki so na voljo: %s\n" +"Privzeto: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" "Default: %%default" msgstr "" +"Polje po katerem se sortirajo zadetki.\n" +"Polja, ki so na voljo: %s\n" +"Privzeto: %%default" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" -msgstr "" +msgstr "Sortiraj zadetke v naraščujočem redu" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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 "" +"Filtriraj rezultate iskanja. Za format iskalnega niza, prosim poglejte " +"dokumentacijo povezano z iskanje v Priročniku za uporabo. Privzeto je " +"iskanje brez filtriranja." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" -msgstr "" +msgstr "Neveljavna polja. Polja, ki so na voljo:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" -msgstr "" +msgstr "Neveljavno sortirno polje. Polja, ki so na voljo:" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" msgstr "" +"Naslednje knjige niso bile dodane ker se že nahajajo v bazi (glej --" +"duplicates možnost):" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" +"%prog add [options] file1 file2 file3 ...\n" +"\n" +"Dodaj izbrane datoteke kot knjige v bazo. Izberete lahko tudi direktorije, " +"poglejte\n" +"z direktoriji povezane možnosti spodaj.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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 "" +"Privzami da vsebuje vsak direktorij samo eno knjigo in da so vse datoteke " +"ista knjiga v različnih formatih." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" -msgstr "" +msgstr "Obdelaj direktorije rekurzivno" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." msgstr "" +"Dodaj knjige v bazo tudi če že obstajajo. Primerjava se izvede po naslovu." -#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" -msgstr "" +msgstr "Določiti morate vsaj eno datoteko za dodajanje" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2823,12 +3809,17 @@ msgid "" "separated list of id numbers (you can get id numbers by using the list " "command). For example, 23,34,57-85\n" msgstr "" +"%prog remove ids\n" +"\n" +"Odstrani knjige, identificirane po id-jih iz baze. id-ji morajo biti ločeni " +"z vejico. (id številke lahko dobite z uporabo ukaza list). Naprimer 23,34,57-" +"85\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" -msgstr "" +msgstr "Vsaj eno knjigo morate določiti za odstranitev" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2836,16 +3827,21 @@ msgid "" "identified by id. You can get id by using the list command. If the format " "already exists, it is replaced.\n" msgstr "" +"%prog add_format [options] id ebook_file\n" +"\n" +"Dodaj eknjig v ebook_file k seznamu formatov, ki so na voljo za logično " +"knjigo identificirano z id-jem. ID lahko dobite z ukazom list. Če format že " +"obstaja, se ga zamenja.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" -msgstr "" +msgstr "Določiti morate id in datotko eknjige" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" -msgstr "" +msgstr "datoteka eknjige mora imeti končnico" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2854,30 +3850,41 @@ msgid "" "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 "" +"\n" +"%prog remove_format [options] id fmt\n" +"\n" +"Odstrani format fmt iz logične knjige identificirane z id-jem. ID lahko " +"dobite z ukazom list. fmt naj bo končnica datoteke, kot je nprimer LRF, TXT " +"ali EPUB. Če logična knjiga nima formata fmt se ne zgodi nič.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" -msgstr "" +msgstr "Določiti morate id in format" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" +"\n" +"%prog show_metadata [options] id\n" +"\n" +"Prikaži meta pdatke shranjene v bazi za knjigo identificirano z id-jem.\n" +"id je identifikacijska številka, ki jo dobite z ukazom list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" -msgstr "" +msgstr "Natisni meta podatke v OPF obliki (XML)" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" -msgstr "" +msgstr "Določiti morate id" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2885,93 +3892,297 @@ msgid "" "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" +"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 "" +"\n" +"%prog set_metadata [options] id /path/to/metadata.opf\n" +"\n" +"Nastavi meta podatke shranjene v podatkovni bazi od calibre za knjigo " +"identificirano z id-jem\n" +"iz OPF datoteke metadata.opf. ID je identifikacijska številka, ki jo dobite " +"z ukazom list. Za\n" +"občutek kako OPF format izgleda lahko uporabite --as-opf stikalo skupaj z " +"ukazom\n" +"show_metadata.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" -msgstr "" +msgstr "Določiti morate id in datoteko z meta podatki" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(in\n" +"an opf file). You can get id numbers from the list command.\n" msgstr "" +"%prog export [options] ids\n" +"\n" +"Izvozi knjige, določene z id-jem (z vejico ločen seznam id-jev) na datotečni " +"sistem.\n" +"Export operacija shrani vse formate knjige, naslovnico in meta podatke (v " +"opf datoteki).\n" +"ID številke lahko dobite z ukazom list.\n" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." -msgstr "" +msgstr "Izvozi vse knjige iz podatkovne baze brez upoštevanja seznama id-jev" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" -msgstr "" +msgstr "Izvozi knjige v podan direktorij. Privzeto je" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" -msgstr "" +msgstr "Izvozi vse knjige v en direktorij" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" -msgstr "" +msgstr "Ustvari imena datotek kot avtor - naslov namesto naslov - avtor" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" -msgstr "" +msgstr "Določiti morate nekaj id-jev ali možnost %s" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "Kopiram <b>%s</b>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "<p>Selitev stare podatkovne baze v knjižnico eknjig v %s<br><center>" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "Krčim bazo" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." +msgstr "Zagon delovnega procesa ni uspel." + +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "Posel ustavljen s strani uporabnika" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "%sUporaba%s: %s\n" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "Ustvaril " + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "Pot do baze v kateri so shranjene knjige" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "Vzorec za ugotavljanje meta podatkov iz datotek" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "Vstopni ključ za isbndb.com" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "Privzet čas neaktivnosti za omrežne operacije (sekunde)" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "Pot do direktorija v katerem so shranjene vaše eknjige" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" -msgstr "" +msgstr "Inicializacija fontconfig knjižnice ni uspela." #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:53 msgid "URL must have the scheme sftp" -msgstr "" +msgstr "URL mora imeti shemo sftp" #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:57 msgid "host must be of the form user@hostname" -msgstr "" +msgstr "naslov strežnika mora biti v formatu user@hostname" #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:68 msgid "Failed to negotiate SSH session: " -msgstr "" +msgstr "Avtentikacija SSH seje ni uspela: " #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:71 msgid "Failed to authenticate with server: %s" -msgstr "" +msgstr "Avtentikacija s strežnikom ni uspela: %s" #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:56 #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77 msgid "Unknown feed" -msgstr "" +msgstr "Neznani feed" #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:95 #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:117 msgid "Untitled article" +msgstr "Neznan članek" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" +"Timeout v sekundah za čakanje odgovora od strežnika. Privzeto: %default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" +"Minimalni interval v sekundah med zaporednimi prenosi. Privzeto: %default s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" +"Kodna tabela znakov za spletne strani, ki jih hočete prenesti. Privzeto je " +"ugibanje uporabljene kodne tabele." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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 "" +"Samo povezavam, ki se ujemajo s tem regularnim izrazom se bo sledilo. Ta " +"možnost se lahko uporabi večkrat, kar pomeni da če povezava ustreza enemu " +"izmed regularnih izrazov, se ji bo sledilo. Privzeto se sledi vsem povezavam." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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 "" +"Vsaka povezava, ki se ujema s tem regularnim izrazom se ignorira. Ta možnost " +"se lahko uporabi večkrat, kar pomeni da če povezava ustreza enemu izmed " +"regularnih izrazov, bo ignorirala. Privzeto se sledi vsem povezavam. Če sta " +"uporabljena tako --filter-regexp kot --match-regexp, potem se najprej " +"upošteva --filter-regexp." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "Ne prenesi CSS oblikovnih informacij." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" +"Naslov za ta recept. Se uporabi za naslov eknjig, ki so ustvarjene iz " +"prenešenih feed-ov." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "Uporabniško ime za zaščitene strani." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "Geslo za zaščitene strani." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" +"Globina v katero se sledi povezavam, ki so prisotne v feed-ih. Privzeto: " +"%dfault" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" +"Direktorij v katerega se shranijo prenešeni feed-i. Privzet je trenutni " +"direktorij." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" +"Uporabno za razvoj receptov. Prisili max_articles_per_feed na 2 in prenese " +"največ dva feed-a." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -2992,210 +4203,134 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" +"Nastavitve za web2disk (uporablja se za prenos web strani na katere kažejo " +"povezave iz feed-ov)" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" -msgstr "" +msgstr "Ne prikaži indikatorja napredka" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." -msgstr "" +msgstr "Prenašam feed-e..." -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" -msgstr "" +msgstr "Neznan Vir Novic" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" -msgstr "" +msgstr "Prenos končan" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" -msgstr "" +msgstr "Prenos naslednjih člankov ni uspel:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " -msgstr "" +msgstr " iz " -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" -msgstr "" +msgstr "Prenos nekaterih delov od naslednjih člankov ni uspel:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" -msgstr "" +msgstr "\tNeuspešne povezave:" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" -msgstr "" +msgstr "Prenos članka ni uspel. Za razlog poženite z --debug možnostjo" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" -msgstr "" +msgstr "Dobljeni feed-i iz indeks strani" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 -msgid "Starting download [%d thread(s)]..." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 -msgid "Feeds downloaded to %s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 -msgid "Could not download cover: %s" -msgstr "" +msgstr "Poskušam prenesti naslovnico ..." #: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +msgid "Starting download [%d thread(s)]..." +msgstr "Začenjam prenos [%d nit(i)]..." + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 +msgid "Feeds downloaded to %s" +msgstr "Feed-i prenešeni v %s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 +msgid "Could not download cover: %s" +msgstr "Prenos naslovnico ne bil mogoč: %s" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" -msgstr "" +msgstr "Prenašam naslovnico iz %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" -msgstr "" +msgstr "Članek brez naslova" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" +"\n" +"Prenešen članek %s iz %s\n" +"%s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" -msgstr "" +msgstr "Članek prenešen: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" -msgstr "" +msgstr "Neuspešen prenos članka: %s iz %s\n" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" -msgstr "" +msgstr "Prenos članka ni uspel: %s" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" -msgstr "" +msgstr "Prenašam feed" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" +"%prog URL\n" +"\n" +"Kjer je URL naprimer http://google.com" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" -msgstr "" +msgstr "Osnovni direktorij v katerega se shrani URL. Privzet je %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" msgstr "" +"Maksimalna globina rekurzije. To je globina povezav. Privzeto %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" msgstr "" +"Maksimalno število prenešenih datotek. To velja samo za datoteke iz <a href> " +"značk. Privzeto je %default" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" -msgstr "" +msgstr "Podrobneje prikaži izhodne informacije. Koristno za razhroščevanje." diff --git a/src/calibre/translations/sv.po b/src/calibre/translations/sv.po new file mode 100644 index 0000000000..50f9f5560a --- /dev/null +++ b/src/calibre/translations/sv.po @@ -0,0 +1,3939 @@ +# Swedish translation for calibre +# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008 +# This file is distributed under the same license as the calibre package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: calibre\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" +"PO-Revision-Date: 2008-09-14 18:45+0000\n" +"Last-Translator: Linus C Unneback <linus@folkdatorn.se>\n" +"Language-Team: Swedish <sv@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: 2008-10-06 00:28+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 +msgid "Unable to detect the %s disk drive. Try rebooting." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 +msgid "The reader has no storage card connected." +msgstr "Läsaren har inga minneskort inkopplade." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 +msgid "%prog [options] LITFILE" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +msgid "Output directory. Defaults to current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 +msgid "Useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 +msgid "OEB ebook created in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +msgid "Set the title. Default: filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 +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:78 +msgid "Set the comment." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +msgid "Set the category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +msgid "Sort key for the title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +msgid "Sort key for the author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 +msgid "Publisher" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +msgid "Path to file containing image to be used as cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 +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:93 +msgid "Output file name. Default is derived from input filename" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 +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:98 +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:100 +msgid "Enable autorotation of images that are wider than the screen width." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +msgid "Set the space between words in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +msgid "Separate paragraphs by blank lines." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +msgid "Add a header to all the pages with title and author." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 +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:111 +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:113 +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:115 +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:117 +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:122 +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:128 +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:134 +msgid "Left margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +msgid "Right margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +msgid "Top margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +msgid "Bottom margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 +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:144 +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:149 +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:153 +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:157 +msgid "Don't add links to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 +msgid "Prevent the automatic detection chapters." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 +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:167 +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:169 +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:179 +msgid "" +"Force a page break before tags whose names match this regular expression." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 +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:184 +msgid "Add detected chapters to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +msgid "Preprocess Baen HTML files to improve generated LRF." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 +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:191 +msgid "Use this option on html0 files from Book Designer." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 +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:202 +msgid "The serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 +msgid "The sans-serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 +msgid "The monospace family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +msgid "Be verbose while processing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +msgid "Convert to LRS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 +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:218 +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:152 +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:167 +msgid "No file to convert specified." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 +msgid "Rendered %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 +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:284 +msgid "Title for generated ebook. Default is to use the filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 +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:289 +msgid "" +"Path to output LRF file. By default a file is created in the current " +"directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 +msgid "" +"Disable normalize (improve contrast) color range for pictures. Default: False" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 +msgid "Maintain picture aspect ratio. Default is to fill the screen." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 +msgid "Disable sharpening." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 +msgid "Don't split landscape images into two portrait images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 +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:309 +msgid "" +"Choose a profile for the device you are generating this LRF for. The default " +"is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 +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:313 +msgid "Don't show progress bar." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 +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:378 +msgid "Output written to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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:316 +msgid "\tBook Designer file detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 +msgid "\tParsing HTML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 +msgid "\tBaen file detected. Re-parsing..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 +msgid "Written preprocessed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 +msgid "Processing %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 +msgid "\tConverting to BBeB..." +msgstr "" + +#: /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 +msgid "Could not parse file: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:537 +msgid "%s is an empty file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 +msgid "Failed to parse link %s %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 +msgid "Cannot add link %s to TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 +msgid "Unable to process image %s. Error: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 +msgid "Unable to process interlaced PNG %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 +msgid "" +"Could not process image: %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 +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:1760 +msgid "" +"Bad table:\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 +msgid "Table has cell that is too large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 +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:1855 +msgid "Could not read cover image: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 +msgid "Cannot read from: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +msgid "Failed to process opf file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 +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:133 +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:134 +msgid "Output LRS file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 +msgid "Parsing LRF..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 +msgid "Creating XML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 +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:114 +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:22 +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:26 +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:607 +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:609 +msgid "Set book ID" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 +msgid "Don't know what this is for" +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:56 +msgid " does not allow copying of text." +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:24 +msgid "Set the authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 +msgid "Set the comment" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 +msgid "A comma separated list of tags to set" +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:37 +#: /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:96 +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:107 +msgid "The ISBN ID of the book you want metadata for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 +msgid "The author whose book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 +msgid "The title of the book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +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:40 +msgid "Usage: %s file.lit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:50 +msgid "Cover saved to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:36 +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/reader.py:421 +msgid "%prog [options] myebook.mobi" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 +msgid "Raw MOBI HTML saved in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 +msgid "Title" +msgstr "" + +#: /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:356 +#: /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:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 +msgid "Comments" +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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/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/password_ui.py:56 +#: /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:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +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:23 +msgid "Basic" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:24 +msgid "Advanced" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 +msgid "Invalid database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 +msgid "Invalid database location.<br>Cannot write to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting database. This may take a while." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 +msgid "Compacting..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +msgid "Configuration" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:236 +msgid "Browse for the new database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 +#: /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:226 +#: /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:229 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +msgid "..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +msgid "Use &Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 +msgid "&Number of covers to show in browse mode (after restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +msgid "Show notification when &new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 +msgid "Ask for &confirmation before deleting files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +msgid "Format for &single file save:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 +msgid "&Priority for conversion jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +msgid "Default network &timeout:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +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:246 +msgid " seconds" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 +msgid "Toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 +msgid "Large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 +msgid "Medium" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 +msgid "Small" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 +msgid "&Button size in toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 +msgid "Show &text in toolbar buttons" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 +msgid "Select visible &columns in library view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 +msgid "Add a directory to the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 +msgid "Remove a directory from the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 +msgid "Free unused diskspace from the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 +msgid "&Compact database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 +msgid "&Metadata from file name" +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:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 +msgid "Author(s)" +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:31 +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:97 +msgid "Choose the format to convert into LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:105 +msgid "Convert %s to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 +msgid "Set conversion defaults" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 +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:256 +msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:257 +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:258 +msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +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:292 +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:293 +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:303 +msgid "<font color=\"gray\">No help available</font>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:404 +msgid "Bulk convert ebooks to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +msgid "Convert to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +msgid "Category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +msgid "Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid "Base &font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +msgid " pts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 +msgid "Embedded Fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +msgid "&Serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 +msgid "S&ans-serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 +msgid "&Monospace:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +msgid "Minimum &indent:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +msgid "&Word spacing:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +msgid "Enable auto &rotation of images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +msgid "Insert &blank lines between paragraphs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "Ignore &tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +msgid "Ignore &colors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Preprocess:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +msgid "Header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Show header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +msgid "&Header format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "Override<br>CSS" +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:552 +#: /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:556 +msgid " px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +msgid "&Convert tables to images (good for large/complex tables)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +msgid "&Multiplier for text size in rendered tables:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +msgid "Title based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 +msgid "&Disable chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 +msgid "&Regular expression:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 +msgid "Add &chapters to table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +msgid "Don't add &links to the table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 +msgid "Tag based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +msgid "&Page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 +msgid "&Force page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 +msgid "Force page break before &attribute:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 +msgid "Detect chapter &at tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 +msgid "Help on item" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 +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; font-" +"family:'Sans Serif'; font-size:9pt;\"></p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:114 +msgid "Edit Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +msgid "Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 +msgid "Author S&ort: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 +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:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +msgid "&Rating:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 +msgid "Rating of this book. 0-5 stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +msgid " stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 +msgid "Add Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +msgid "Open Tag Editor" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 +msgid "&Remove tags:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 +msgid "Comma separated list of tags to remove from the books. " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 +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:284 +msgid "<b>Could not fetch cover.</b><br/>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 +msgid "Could not fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "Cannot fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 +msgid "You must specify the ISBN identifier for this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +msgid "Edit Meta Information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 +msgid "Swap the author and title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 +msgid "Fetch metadata from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 +msgid "Available Formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 +msgid "Add a new format for this book to the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +msgid "Remove the selected formats for this book from the database." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +msgid "Fetch cover image from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +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:317 +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/password_ui.py:57 +msgid "&Username:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 +msgid "&Password:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 +msgid "&Show password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:15 +msgid "Author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:17 +msgid "Tag" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Series" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 +msgid "Format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:21 +msgid "Any" +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:73 +msgid "Advanced Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:74 +msgid "Match a&ll of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:75 +msgid "Match a&ny of the following criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:76 +msgid "Search criteria" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:77 +msgid "More" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:78 +msgid "Fewer" +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:63 +msgid "No recipe selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 +msgid "The attached file: %s is a recipe to download %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 +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:214 +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 +msgid "Switch to Basic mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 +msgid "Feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:111 +msgid "The feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 +msgid "Feed must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:116 +msgid "The feed %s must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 +msgid "Already exists" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:122 +msgid "This feed has already been added to the recipe" +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:195 +msgid "Invalid input" +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:196 +msgid "<p>Could not create recipe. Error:<br>%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 +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:202 +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:188 +msgid "Choose a recipe file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:188 +msgid "Recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:208 +msgid "Add custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:209 +msgid "Available user recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:210 +msgid "Add/Update &recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:211 +msgid "&Remove recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:212 +msgid "&Share recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:213 +msgid "&Load recipe from file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 +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:219 +msgid "Recipe &title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:220 +msgid "&Oldest article:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:221 +msgid "The oldest article to download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:222 +msgid " days" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:223 +msgid "&Max. number of articles per feed:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:224 +msgid "Maximum number of articles to download per feed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:225 +msgid "Feeds in recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:227 +msgid "Remove feed from recipe" +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:233 +msgid "Add feed to recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:231 +msgid "&Feed title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:232 +msgid "Feed &URL:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:234 +msgid "&Add feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:235 +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:236 +msgid "Recipe source code (python)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 +msgid "" +"<p>Set a regular expression pattern to use when trying to guess ebook " +"metadata from filenames. <p>A <a href=\"http://docs.python.org/lib/re-" +"syntax.html\">reference</a> on the syntax of regular expressions is " +"available.<p>Use the <b>Test</b> functionality below to test your regular " +"expression on a few sample filenames." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:98 +msgid "Regular &expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:99 +msgid "&Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:100 +msgid "File &name:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:101 +msgid "Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:102 +msgid "Title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:103 +msgid "Regular expression group name (?P<title>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:107 +#: /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/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:105 +msgid "Authors:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 +msgid "Regular expression group name (?P<authors>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 +msgid "Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 +msgid "Regular expression group name (?P<series>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 +msgid "Series index:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 +msgid "Regular expression group name (?P<series_index>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 +msgid "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:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 +msgid "Cannot kill job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 +msgid "None" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +msgid "Book <font face=\"serif\">%s</font> of %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 +msgid "Double click to <b>edit</b> me<br><br>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 +msgid "Size (MB)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 +msgid "Date" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 +msgid "Rating" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 +msgid "Timestamp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 +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 +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 +msgid "Back" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:134 +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 +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:85 +msgid "Error communicating with device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 +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:99 +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:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +msgid "Send to main memory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "Send to storage card" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 +msgid "and delete from library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 +msgid "Send to storage card by default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +msgid "Edit metadata individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +msgid "Edit metadata in bulk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 +msgid "Add books from a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 +msgid "" +"Add books recursively (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:141 +msgid "" +"Add books recursively (Multiple books per directory, assumes every ebook " +"file is a different book)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 +msgid "Save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 +msgid "Save to disk in a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +msgid "Save only %s format to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 +msgid "View" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 +msgid "View specific format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +msgid "Convert individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +msgid "Bulk convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 +msgid "Set defaults for conversion of comics" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 +msgid "Device: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 +msgid "Connected " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 +msgid "Device database corrupted" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 +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:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 +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:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 +msgid "Duplicates found!" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 +msgid "Uploading books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 +msgid "No space on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 +msgid "" +"<p>Cannot upload books to device there is no more free space available " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 +msgid "Confirm delete" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 +msgid "Are you sure you want to delete these %d books?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 +msgid "Deleting books from device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +msgid "Cannot edit metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "No books selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 +msgid "Sending books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 +msgid "No suitable formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 +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:758 +msgid "Cannot save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 +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:773 +msgid "Could not save some ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 +msgid "Fetching news from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 +msgid "News fetched. Uploading to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +msgid "No book selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 +msgid "Cannot view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 +msgid "Choose the format to view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 +msgid "%s has no available formats." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 +msgid "Cannot configure while there are running jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +msgid "Invalid database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 +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:1041 +msgid "Could not move database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 +msgid "No detailed info available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 +msgid "No detailed information is available for books on the device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 +msgid "Error talking to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 +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:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 +msgid "Conversion Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 +msgid "Database does not exist" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 +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:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 +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:1216 +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:1216 +msgid "Update available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +msgid "calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +msgid "Advanced search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +msgid "Alt+S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +msgid "&Search:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +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:277 +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:278 +msgid "Reset Quick Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 +msgid "Add books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 +msgid "A" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 +msgid "Remove books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 +msgid "Del" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 +msgid "Edit meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 +msgid "E" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 +msgid "Send to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 +msgid "S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 +msgid "Fetch news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 +msgid "F" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 +msgid "Convert E-books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 +msgid "C" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 +msgid "V" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:17 +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 +msgid "ERROR: Unhandled exception" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:32 +msgid "Add a custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 +msgid "" +"<p>Please enter your username and password for %s<br>If you do not have one, " +"please subscribe to get access to the articles.<br/> Click OK to proceed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 +msgid "Custom news sources" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +msgid "Jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 +msgid "Click to see list of active jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to browse books by their covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 +msgid "Click to turn off Cover Browsing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 +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:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:178 +msgid "Library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 +msgid "" +"Reader\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 +msgid "" +"Card\n" +"%s available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 +msgid "Click to see the list of books available on your computer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 +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:186 +msgid "Click to see the list of books on the storage card in your reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 +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:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 +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:94 +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" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +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:98 +msgid "Sort results in ascending order" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 +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:106 +msgid "Invalid fields. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 +msgid "Invalid sort field. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 +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:201 +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:210 +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:212 +msgid "Process directories recursively" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 +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:219 +msgid "You must specify at least one file to add" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 +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:249 +msgid "You must specify at least one book to remove" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 +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:280 +msgid "You must specify an id and an ebook file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 +msgid "ebook file must have an extension" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 +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:306 +msgid "You must specify an id and a format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 +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:332 +msgid "Print metadata in OPF form (XML)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 +msgid "You must specify an id" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 +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:364 +msgid "You must specify an id and a metadata file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 +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:384 +msgid "Export all books in database, ignoring the list of ids." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 +msgid "Export books to the specified directory. Default is" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 +msgid "Export all books into a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 +msgid "Create file names as author - title instead of title - author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 +msgid "You must specify some ids or the %s option" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 +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:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 +msgid "Could not launch worker process." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 +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:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77 +msgid "Unknown feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:95 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:117 +msgid "Untitled article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 +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:86 +msgid "" +"Options to control web2disk (used to fetch websites linked from feeds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 +msgid "Dont show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 +msgid "Fetching feeds..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 +msgid "Unknown News Source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 +msgid "Download finished" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 +msgid "Failed to download the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 +msgid " from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 +msgid "Failed to download parts of the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 +msgid "\tFailed links:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 +msgid "Could not fetch article. Run with --debug to see the reason" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 +msgid "Got feeds from index page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 +msgid "Trying to download cover..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +msgid "Starting download [%d thread(s)]..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 +msgid "Feeds downloaded to %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 +msgid "Could not download cover: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 +msgid "Downloading cover from %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 +msgid "Untitled Article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 +msgid "" +"\n" +"Downloaded article %s from %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 +msgid "Article downloaded: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 +msgid "Failed to download article: %s from %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 +msgid "Article download failed: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 +msgid "Fetching feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 +msgid "" +"%prog URL\n" +"\n" +"Where URL is for example http://google.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 +msgid "Base directory into which URL is saved. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +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:408 +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:419 +msgid "Show detailed output information. Useful for debugging" +msgstr "" diff --git a/src/calibre/translations/te.po b/src/calibre/translations/te.po index 971ff80cf0..f789ef13cd 100644 --- a/src/calibre/translations/te.po +++ b/src/calibre/translations/te.po @@ -7,252 +7,520 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" -"POT-Creation-Date: 2008-08-03 09:01+0000\n" +"POT-Creation-Date: 2008-09-24 02:10+0000\n" "PO-Revision-Date: 2008-06-24 13:22+0000\n" "Last-Translator: వీవెన్ (Veeven) <Unknown>\n" "Language-Team: Telugu <te@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: 2008-08-04 16:52+0000\n" +"X-Launchpad-Export-Date: 2008-10-06 00:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:178 -msgid "%sUsage%s: %s\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/__init__.py:215 -msgid "Created by " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:113 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:147 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:175 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:131 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:149 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:187 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:215 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:356 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:403 msgid "The reader has no storage card connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:780 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:48 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:59 +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:61 +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:63 +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:64 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:66 +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:75 +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:77 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:80 +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:83 +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:89 +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:91 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:93 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:95 +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:97 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:99 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:101 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:114 +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:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:630 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:726 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:287 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /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:57 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:111 +#: /home/kovid/work/calibre/src/calibre/library/database.py:910 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1431 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:454 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:725 +msgid "Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:92 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:136 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to an epub file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:61 +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:181 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:810 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:31 +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:85 +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:390 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:608 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:615 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:617 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:619 +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:621 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:623 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:625 +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:627 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:629 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:631 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:633 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:635 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:637 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:639 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:645 +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 references 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/reader.py:813 msgid "%prog [options] LITFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:783 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:404 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:816 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:786 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:819 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:822 msgid "Useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:797 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:833 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:444 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 msgid "Set the title. Default: filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:75 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:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:239 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:174 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:314 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:926 -#: /home/kovid/work/calibre/src/calibre/library/database.py:904 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1412 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1542 -msgid "Unknown" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 msgid "Set the comment." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 msgid "Set the category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 msgid "Sort key for the title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 msgid "Sort key for the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:16 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:423 msgid "Publisher" msgstr "ప్రచురణకర్త" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 msgid "Path to file containing image to be used as cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:90 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:91 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 msgid "Output file name. Default is derived from input filename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:95 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:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:98 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:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:100 msgid "Enable autorotation of images that are wider than the screen width." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 msgid "Set the space between words in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 msgid "Separate paragraphs by blank lines." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 msgid "Add a header to all the pages with title and author." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:109 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:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:111 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:111 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:113 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:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:115 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:115 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:117 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:120 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:122 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:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:128 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:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 msgid "Left margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 msgid "Right margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 msgid "Top margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 msgid "Bottom margin of page. Default is %default px." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:142 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:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:144 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:147 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:149 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:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:153 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:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:157 msgid "Don't add links to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:161 msgid "Prevent the automatic detection chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 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:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 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\". Default is %default" +"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:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:169 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 " @@ -263,12 +531,12 @@ msgid "" "has only a few elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:177 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 msgid "" "Force a page break before tags whose names match this regular expression." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:181 msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " @@ -276,25 +544,25 @@ msgid "" "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 msgid "Add detected chapters to the table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 msgid "Preprocess Baen HTML files to improve generated LRF." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:189 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:189 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:191 msgid "Use this option on html0 files from Book Designer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 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 " @@ -302,33 +570,33 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:202 msgid "The serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 msgid "The sans-serif family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 msgid "The monospace family of fonts to embed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 msgid "Be verbose while processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 msgid "Convert to LRS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:216 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:216 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:218 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 " @@ -336,7 +604,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:152 msgid "" "any2lrf [options] myfile\n" "\n" @@ -347,92 +615,114 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:167 msgid "No file to convert specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:200 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:218 msgid "Rendered %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:230 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:221 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:278 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:236 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 msgid "Title for generated ebook. Default is to use the filename." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:238 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 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:241 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:289 msgid "" "Path to output LRF file. By default a file is created in the current " "directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:243 -msgid "Number of colors for Grayscale image conversion. Default: %default" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:245 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:293 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:247 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:249 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 msgid "Disable sharpening." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Don't split landscape images into two portrait images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:253 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +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:303 +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:305 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 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:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Choose a profile for the device you are generating this LRF for. The default " "is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:257 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 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:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "Don't show progress bar." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" -"Convert a comic in a CBZ or CBR file to an LRF ebook. \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:328 -msgid "Rendering comic pages..." -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:378 msgid "Output written to" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:419 +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" @@ -441,7 +731,7 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -449,24 +739,24 @@ msgid "" "%prog converts mybook.fb2 to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +#: /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:24 +#: /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:22 +#: /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:24 +#: /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:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 msgid "Fetching of recipe failed: " msgstr "" @@ -494,71 +784,71 @@ msgstr "" msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 +#: /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 msgid "Could not parse file: %s" 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:537 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:950 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:988 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1003 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1752 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1758 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:1754 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1760 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1776 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1782 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1806 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1812 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:1849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1855 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1852 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1858 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1987 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -569,7 +859,7 @@ msgid "" "convert a whole tree of HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:22 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" "Usage: %prog [options] mybook.lit\n" "\n" @@ -577,48 +867,48 @@ msgid "" "%prog converts mybook.lit to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:132 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:133 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:133 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:134 msgid "Output LRS file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:152 msgid "Parsing LRF..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:155 msgid "Creating XML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:157 msgid "LRS written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:243 +#: /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:263 +#: /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:264 +#: /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:266 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 msgid "Verbose processing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:268 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." msgstr "" @@ -636,7 +926,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:21 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:22 msgid "Set the book title" msgstr "" @@ -653,7 +943,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:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:26 msgid "The category this book belongs to. E.g.: History" msgstr "" @@ -692,20 +982,20 @@ msgid "" "%prog converts mybook.mobi to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:42 +#: /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:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:56 msgid " does not allow copying of text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:54 +#: /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:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 msgid "" "%prog [options] mybook.pdf\n" "\n" @@ -713,21 +1003,21 @@ msgid "" "%prog converts mybook.pdf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:402 +#: /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:404 +#: /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:416 +#: /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:20 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 msgid "" "%prog [options] mybook.rtf\n" "\n" @@ -735,7 +1025,13 @@ msgid "" "%prog converts mybook.rtf to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:17 +#: /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" @@ -743,23 +1039,33 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:24 msgid "Set the authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:27 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:28 msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:117 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:113 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 msgid "Usage:" msgstr "వాడుక:" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:95 +#: /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:37 +#: /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:96 msgid "" "\n" "%prog [options] key\n" @@ -773,38 +1079,38 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:106 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "The ISBN ID of the book you want metadata for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:109 msgid "The author whose book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:111 msgid "The title of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:113 msgid "The publisher of the book to search for." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:46 +#: /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:47 +#: /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:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:81 +#: /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:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 msgid "" "\n" "%prog [options] ISBN\n" @@ -824,96 +1130,221 @@ msgstr "" msgid "Usage: pdf-meta file.pdf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:37 -msgid "No filename specified." +#: /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/reader.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:421 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:423 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:442 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:26 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:259 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +msgid "Send downloaded periodical content to device automatically" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Options for the LRF ebook viewer" +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:144 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +msgid "View book on device" +msgstr "" + +#: /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/dialogs/search.py:14 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:784 msgid "Title" msgstr "శీర్షిక" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /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:356 +#: /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:304 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:54 msgid "Comments" msgstr "వ్యాఖ్యలు" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:79 +#: /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:238 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:52 +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:237 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +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/warning_ui.py:52 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:57 +#: /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/password_ui.py:56 +#: /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:38 +#: /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:53 +#: /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:80 +#: /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:81 +#: /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:82 +#: /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:83 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:84 +#: /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:85 +#: /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:86 +#: /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:87 +#: /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:88 -msgid "Dont so&rt" +#: /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:23 @@ -924,53 +1355,57 @@ msgstr "ప్రాధమిక" msgid "Advanced" msgstr "ఉన్నత" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "<br>Must be a directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -msgid "Invalid database location " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:130 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:127 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:131 msgid "Invalid database location.<br>Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:143 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 msgid "Configuration" msgstr "స్వరూపణం" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 -msgid "&Location of books database (library1.db)" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +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:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 -#: /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:266 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 +#: /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:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 #: /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 @@ -978,99 +1413,116 @@ 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:228 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "..." msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 msgid "&Number of covers to show in browse mode (after restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "Ask for &confirmation before deleting files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:243 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 msgid " seconds" msgstr " క్షణాలు" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:247 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:526 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:249 +msgid "LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:250 +msgid "EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:251 +msgid "&Output format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:252 msgid "Toolbar" msgstr "పనిముట్ల పట్టీ" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:253 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:254 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:255 msgid "Small" msgstr "చిన్న" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:256 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:257 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:258 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 -msgid "Frequently used directories" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:260 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:262 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:264 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:265 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:266 msgid "&Metadata from file name" msgstr "" @@ -1078,10 +1530,335 @@ msgstr "" msgid "ERROR" msgstr "పొరపాటు" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:46 +msgid "Bulk convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:48 +msgid "Convert %s to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 +msgid "Look & Feel" +msgstr "రూపు రేఖలు" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 +msgid "Page Setup" +msgstr "పేజీ అమరిక" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:80 +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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:81 +msgid "" +"Adjust the look of the generated EPUB file by specifying things like font " +"sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:82 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:166 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:45 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:54 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:222 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:232 +msgid "Choose the format to convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:334 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:336 +#: /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:312 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +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:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +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:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:348 +#: /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:291 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +#: /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:292 +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:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /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:295 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:354 +#: /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:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +msgid "Book " +msgstr "పుస్తకం " + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:358 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:367 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:368 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:369 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:370 +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:375 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:756 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:785 msgid "Author(s)" msgstr "రచయిత(లు)" @@ -1165,34 +1942,6 @@ msgstr "" msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:291 -msgid "Metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:292 -msgid "Look & Feel" -msgstr "రూపు రేఖలు" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:293 -msgid "Page Setup" -msgstr "పేజీ అమరిక" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Chapter Detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:92 -msgid "No available formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 -msgid "Cannot convert %s as this book has no supported formats" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:97 msgid "Choose the format to convert into LRF" msgstr "" @@ -1202,33 +1951,10 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:341 msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:43 -msgid "Cannot read" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:44 -msgid "You do not have permission to read the file: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:52 -msgid "Error reading file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 -msgid "<p>There was an error reading from file: <br /><b>" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 -msgid " is not a valid picture" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:255 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " @@ -1267,10 +1993,6 @@ msgid "" "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:294 -msgid "Fine tune the detection of chapter and section headings." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:303 msgid "<font color=\"gray\">No help available</font>" msgstr "<font color=\"gray\">సహాయమేమీ అందుబాటులో లేదు</font>" @@ -1279,276 +2001,156 @@ msgstr "<font color=\"gray\">సహాయమేమీ అందుబాటు msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "Category" msgstr "వర్గం" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Options" msgstr "ఎంపికలు" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 -msgid "Book Cover" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 -msgid "Change &cover image:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 -msgid "Browse for an image to use as the cover of this book." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -msgid "Use cover from &source file" -msgstr "" - -#: /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:263 -msgid "&Title: " -msgstr "" - -#: /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:264 -msgid "Change the title of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 -msgid "&Author(s): " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 -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/lrf_single_ui.py:519 -msgid "Author So&rt:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -msgid "&Publisher: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 -msgid "Change the publisher of this book" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Ta&gs: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /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:278 -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/lrf_single_ui.py:525 -#: /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:281 -msgid "&Series:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /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:282 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 -msgid "List of known series. You can add new series." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -msgid "Series index." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 -msgid "Book " -msgstr "పుస్తకం " - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /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:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Embedded Fonts" 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:531 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "S&ans-serif:" 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:533 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 -msgid "Source en&coding:" -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:535 msgid "Minimum &indent:" 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:537 msgid "&Word spacing:" 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:539 msgid "Enable auto &rotation of images" msgstr "" -#: /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:540 msgid "Insert &blank lines between paragraphs" 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:541 msgid "Ignore &tables" msgstr "" -#: /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:542 msgid "Ignore &colors" 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:543 msgid "&Preprocess:" 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:544 msgid "Header" 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:545 msgid "&Show header" 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:546 msgid "&Header format:" 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:547 msgid "Override<br>CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 -msgid "&Left Margin:" -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:552 #: /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:556 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -msgid "&Right Margin:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /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:558 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Title based detection" msgstr "" -#: /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:560 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "&Regular expression:" msgstr "" -#: /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:562 msgid "Add &chapters to table of contents" 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:563 msgid "Don't add &links to the table of contents" 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:564 msgid "Tag based detection" 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:565 msgid "&Page break before tag:" 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:566 msgid "&Force page break before tag:" 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:567 msgid "Force page break before &attribute:" 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:568 msgid "Detect chapter &at tag:" 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:569 msgid "Help on item" 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:570 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:'Candara'; font-size:11pt; 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:'Sans Serif'; font-size:9pt;\"></p></body></html>" @@ -1559,36 +2161,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 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:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid " stars" msgstr "" @@ -1598,8 +2200,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 msgid "Open Tag Editor" msgstr "" @@ -1611,71 +2213,76 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:254 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:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:290 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +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:298 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 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:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid "Change password" msgstr "సంకేతపదం మార్చు" @@ -1704,13 +2311,15 @@ msgid "Tag" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Series" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:718 msgid "Format" msgstr "" @@ -2017,11 +2626,11 @@ 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/widgets.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:61 +#: /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 "" @@ -2054,101 +2663,102 @@ msgstr "" msgid "ISBN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 msgid "Job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 msgid "Status" msgstr "స్థితి" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 msgid "Progress" msgstr "ప్రగతి" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 msgid "Running time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 -msgid "Error" -msgstr "పొరపాటు" +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:346 +#: /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/jobs.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:170 msgid "Cannot kill job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:377 -msgid "" -"Cannot kill jobs that are communicating with the device as this may cause " -"data corruption." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:163 +msgid "Cannot kill jobs that communicate with the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:381 -msgid "Cannot kill already completed jobs." +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:167 +msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:171 +msgid "Cannot kill waiting job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:245 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:759 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:788 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:242 -msgid "Formats" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:247 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:410 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:786 msgid "Size (MB)" msgstr "పరిమాణం (మెబై)" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:787 msgid "Date" msgstr "తేదీ" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:422 msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:690 -msgid "Path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:723 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:794 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:823 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -2168,15 +2778,15 @@ msgstr "" msgid "<b>Changes will only take effect after a restart.</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:63 +#: /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:154 +#: /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:154 +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 msgid "No matches found" msgstr "" @@ -2220,118 +2830,132 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:85 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 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:96 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 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:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:120 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:122 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:139 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 msgid "" "Add books recursively (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:137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:141 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:292 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:298 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 -msgid "Set defaults for conversion to LRF" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 -msgid " detected." +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:220 +msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1160 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +msgid "Migrating database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:357 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:358 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:380 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:391 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:392 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -2347,307 +2971,287 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:533 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:404 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:492 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:568 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:569 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:600 msgid "Confirm delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 msgid "Are you sure you want to delete these %d books?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:613 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:586 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:607 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:829 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:738 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:741 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 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:702 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:758 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:769 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:750 -msgid "Fetch news from " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:801 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:812 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:772 -msgid "Cannot convert" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:794 -msgid "Starting Bulk conversion of %d books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 -msgid "Convert book %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:842 -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/main.py:843 -msgid "Could not convert some books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:878 -msgid "Convert comic %d of %d (%s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 -msgid "Convert book: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 -msgid "Convert comic: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1001 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1019 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:929 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:961 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1038 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:966 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1000 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1095 -msgid "Copying database to " +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1022 +msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1024 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1034 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1035 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:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1041 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1061 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1141 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1062 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1103 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1104 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:1235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1126 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1130 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1146 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1147 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:1305 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 +msgid "Choose new location for database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 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:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1216 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 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:262 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 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:263 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:283 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:284 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:285 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:287 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:288 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:289 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:290 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:291 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:295 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:296 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:297 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:299 msgid "V" msgstr "" @@ -2657,7 +3261,7 @@ msgid "" "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 msgid "ERROR: Unhandled exception" msgstr "" @@ -2675,78 +3279,132 @@ msgstr "" msgid "Custom news sources" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 msgid "Jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:117 msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:151 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:41 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:136 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:325 +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:231 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:326 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:354 +msgid "Fetch news from " +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:39 +#: /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:169 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178 msgid "Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179 msgid "" "Reader\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180 msgid "" "Card\n" "%s available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184 msgid "Click to see the list of books available on your computer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186 msgid "Click to see the list of books on the storage card in your reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:27 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:29 msgid "" -"Path to the calibre database. Default is to use the path stored in the " +"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:82 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:37 +msgid "Using library at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:86 msgid "" "%prog list [options]\n" "\n" -"List the books available in the calibre database. \n" +"List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:90 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:94 msgid "" "The fields to display when listing books in the database. Should be a comma " "separated list of fields.\n" @@ -2754,68 +3412,68 @@ msgid "" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:92 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 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:94 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:98 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:96 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:100 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:103 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:106 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:110 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:113 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:177 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:198 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 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" +"the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 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:209 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:212 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:214 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:216 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:219 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:237 msgid "" "%prog remove ids\n" "\n" @@ -2824,11 +3482,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:249 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:269 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2837,15 +3495,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2855,29 +3513,29 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:306 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:324 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" +"id.\n" +"id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:332 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:337 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2885,62 +3543,115 @@ msgid "" "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" +"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:361 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:364 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:376 msgid "" -"%prog export [options] ids \n" +"%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" +"(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:381 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:388 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:395 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:405 msgid "" "%%prog command [options] [arguments]\n" "\n" -"%%prog is the command line interface to the calibre books database. \n" +"%%prog is the command line interface to the calibre books database.\n" "\n" "command is one of:\n" " %s\n" -" \n" +"\n" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:347 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:923 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:936 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:996 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:969 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1013 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:361 msgid "Could not launch worker process." msgstr "" +#: /home/kovid/work/calibre/src/calibre/parallel.py:781 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:39 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +msgid "Created by " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:514 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:516 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:518 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:520 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:522 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:524 +msgid "The language in which to display the user interface" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:169 msgid "Could not initialize the fontconfig library" msgstr "" @@ -2971,7 +3682,121 @@ msgstr "" msgid "Untitled article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:16 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:19 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:21 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:402 +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:23 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:410 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:25 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:412 +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:27 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:414 +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:29 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:416 +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:31 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:418 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:89 +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:38 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:93 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +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:42 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:44 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:50 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:100 +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:52 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:102 +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:54 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:56 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:106 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:58 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:108 +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:62 msgid "" "%%prog [options] ARG\n" "\n" @@ -2992,210 +3817,123 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:86 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:40 -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:44 -msgid "Be more verbose while processing." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:46 -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:47 -msgid "Username for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:48 -msgid "Password for sites that require a login to access content." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 -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 -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 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:104 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 -msgid "Very verbose output, useful for debugging." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 -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:70 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:580 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:119 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:607 msgid "Fetching feeds..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:34 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:35 msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:475 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:498 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:477 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:500 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:479 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:485 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:502 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:508 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:483 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:506 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:487 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:510 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:586 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:584 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:611 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:588 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:615 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:640 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:653 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:682 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:663 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:692 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:668 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:697 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:702 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:737 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:748 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:791 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:797 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:803 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:765 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:808 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:780 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:823 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:382 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:385 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:399 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:388 -msgid "" -"Timeout in seconds to wait for a response from the server. Default: %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:391 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 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:394 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:408 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:396 -msgid "" -"Minimum interval in seconds between consecutive fetches. Default is %default " -"s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:398 -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/fetch/simple.py:400 -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/fetch/simple.py:402 -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/fetch/simple.py:404 -msgid "Do not download CSS stylesheets." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:405 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:419 msgid "Show detailed output information. Useful for debugging" msgstr "" diff --git a/src/calibre/utils/PythonMagickWand.py b/src/calibre/utils/PythonMagickWand.py index 301557c369..3c83ab4680 100644 --- a/src/calibre/utils/PythonMagickWand.py +++ b/src/calibre/utils/PythonMagickWand.py @@ -80,9 +80,9 @@ elif iswindows: if isfrozen else 'CORE_RL_wand_' else: _lib = util.find_library('MagickWand') + if _lib is None: + _lib = util.find_library('Wand') - - _magick = _magick_error = None try: _magick = ctypes.CDLL(_lib) diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index baf85186c1..cd5944d3c4 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -8,16 +8,16 @@ Manage application-wide preferences. ''' import os, re, cPickle, textwrap from copy import deepcopy +from functools import partial from optparse import OptionParser as _OptionParser from optparse import IndentedHelpFormatter from PyQt4.QtCore import QString from calibre.constants import terminal_controller, iswindows, isosx, \ - __appname__, __version__, __author__ + __appname__, __version__, __author__, plugins from calibre.utils.lock import LockError, ExclusiveFile from collections import defaultdict if iswindows: - from calibre import plugins config_dir = plugins['winutil'][0].special_folder_path(plugins['winutil'][0].CSIDL_APPDATA) if not os.access(config_dir, os.W_OK|os.X_OK): config_dir = os.path.expanduser('~') @@ -28,8 +28,10 @@ else: bdir = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME', '~/.config'))) config_dir = os.path.join(bdir, 'calibre') -if not os.path.exists(config_dir): - os.makedirs(config_dir, mode=448) # 0700 == 448 +def make_config_dir(): + if not os.path.exists(config_dir): + os.makedirs(config_dir, mode=448) # 0700 == 448 + class CustomHelpFormatter(IndentedHelpFormatter): @@ -45,7 +47,7 @@ class CustomHelpFormatter(IndentedHelpFormatter): opts = self.option_strings[option] opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: - opts = "%*s%s\n" % (self.current_indent, "", + opts = "%*s%s\n" % (self.current_indent, "", terminal_controller.GREEN+opts+terminal_controller.NORMAL) indent_first = self.help_position else: # start help on same line as opts @@ -160,6 +162,12 @@ class Option(object): self.switches = switches self.help = help.replace('%default', repr(default)) if help else None self.type = type + if self.type is None and action is None and choices is None: + if isinstance(default, float): + self.type = 'float' + elif isinstance(default, int) and not isinstance(default, bool): + self.type = 'int' + self.choices = choices self.check = check self.group = group @@ -168,7 +176,13 @@ class Option(object): self.metavar = metavar def __eq__(self, other): - return self.name == getattr(other, 'name', None) + return self.name == getattr(other, 'name', other) + + def __repr__(self): + return 'Option: '+self.name + + def __str__(self): + return repr(self) class OptionValues(object): @@ -200,6 +214,29 @@ class OptionSet(object): raise ValueError('A group by the name %s already exists in this set'%name) self.groups[name] = description self.group_list.append(name) + return partial(self.add_opt, group=name) + + def update(self, other): + for name in other.groups.keys(): + self.groups[name] = other.groups[name] + for pref in other.preferences: + if pref in self.preferences: + self.preferences.remove(pref) + self.preferences.append(pref) + + def smart_update(self, opts1, opts2): + ''' + Updates the preference values in opts1 using only the non-default preference values in opts2. + ''' + for pref in self.preferences: + new = getattr(opts2, pref.name, pref.default) + if new != pref.default: + setattr(opts1, pref.name, new) + + def remove_opt(self, name): + if name in self.preferences: + self.preferences.remove(name) + def add_opt(self, name, switches=[], help=None, type=None, choices=None, group=None, default=None, action=None, metavar=None): @@ -213,7 +250,7 @@ class OptionSet(object): option will not be added to the command line parser. :param help: Help text. :param type: Type checking of option values. Supported types are: - `None, 'choice', 'complex', 'float', 'int', 'long', 'string'`. + `None, 'choice', 'complex', 'float', 'int', 'string'`. :param choices: List of strings or `None`. :param group: Group this option belongs to. You must previously have created this group with a call to :method:`add_group`. @@ -234,7 +271,7 @@ class OptionSet(object): parser = OptionParser(usage, gui_mode=gui_mode) groups = defaultdict(lambda : parser) for group, desc in self.groups.items(): - groups[group] = parser.add_group(group, desc) + groups[group] = parser.add_option_group(group.upper(), desc) for pref in self.preferences: if not pref.switches: @@ -267,11 +304,17 @@ class OptionSet(object): def parse_string(self, src): options = {'cPickle':cPickle} + if not isinstance(src, unicode): + src = src.decode('utf-8') if src is not None: exec src in options opts = OptionValues() for pref in self.preferences: - setattr(opts, pref.name, options.get(pref.name, pref.default)) + val = options.get(pref.name, pref.default) + formatter = __builtins__.get(pref.type, None) + if callable(formatter): + val = formatter(val) + setattr(opts, pref.name, val) return opts @@ -279,7 +322,7 @@ class OptionSet(object): prefs = [pref for pref in self.preferences if pref.group == name] lines = ['### Begin group: %s'%(name if name else 'DEFAULT')] if desc: - lines += map(lambda x: '# '+x for x in desc.split('\n')) + lines += map(lambda x: '# '+x, desc.split('\n')) lines.append(' ') for pref in prefs: lines.append('# '+pref.name.replace('_', ' ')) @@ -304,25 +347,44 @@ class OptionSet(object): groups = [self.render_group(name, self.groups.get(name, ''), opts) \ for name in [None] + self.group_list] return src + '\n\n'.join(groups) + +class ConfigInterface(object): -class Config(object): - - def __init__(self, basename, description=''): - self.config_file_path = os.path.join(config_dir, basename+'.py') + def __init__(self, description): self.option_set = OptionSet(description=description) self.add_opt = self.option_set.add_opt self.add_group = self.option_set.add_group + self.remove_opt = self.remove = self.option_set.remove_opt + self.parse_string = self.option_set.parse_string + + def update(self, other): + self.option_set.update(other.option_set) def option_parser(self, usage='', gui_mode=False): return self.option_set.option_parser(user_defaults=self.parse(), usage=usage, gui_mode=gui_mode) + + def smart_update(self, opts1, opts2): + self.option_set.smart_update(opts1, opts2) + +class Config(ConfigInterface): + ''' + A file based configuration. + ''' + + def __init__(self, basename, description=''): + ConfigInterface.__init__(self, description) + self.config_file_path = os.path.join(config_dir, basename+'.py') + def parse(self): - try: - with ExclusiveFile(self.config_file_path) as f: - src = f.read() - except LockError: - raise IOError('Could not lock config file: %s'%self.config_file_path) + src = '' + if os.path.exists(self.config_file_path): + try: + with ExclusiveFile(self.config_file_path) as f: + src = f.read().decode('utf-8') + except LockError: + raise IOError('Could not lock config file: %s'%self.config_file_path) return self.option_set.parse_string(src) def as_string(self): @@ -330,7 +392,7 @@ class Config(object): return '' try: with ExclusiveFile(self.config_file_path) as f: - return f.read() + return f.read().decode('utf-8') except LockError: raise IOError('Could not lock config file: %s'%self.config_file_path) @@ -338,6 +400,8 @@ class Config(object): if not self.option_set.has_option(name): raise ValueError('The option %s is not defined.'%name) try: + if not os.path.exists(config_dir): + make_config_dir() with ExclusiveFile(self.config_file_path) as f: src = f.read() opts = self.option_set.parse_string(src) @@ -346,22 +410,21 @@ class Config(object): src = self.option_set.serialize(opts)+ '\n\n' + footer + '\n' f.seek(0) f.truncate() + if isinstance(src, unicode): + src = src.encode('utf-8') f.write(src) except LockError: raise IOError('Could not lock config file: %s'%self.config_file_path) -class StringConfig(object): +class StringConfig(ConfigInterface): + ''' + A string based configuration + ''' def __init__(self, src, description=''): + ConfigInterface.__init__(self, description) self.src = src - self.option_set = OptionSet(description=description) - self.add_opt = self.option_set.add_opt - self.option_parser = self.option_set.option_parser - def option_parser(self, usage='', gui_mode=False): - return self.option_set.option_parser(user_defaults=self.parse(), - usage=usage, gui_mode=gui_mode) - def parse(self): return self.option_set.parse_string(self.src) @@ -412,9 +475,11 @@ class DynamicConfig(dict): def __init__(self, name='dynamic'): self.name = name self.file_path = os.path.join(config_dir, name+'.pickle') - with ExclusiveFile(self.file_path) as f: - raw = f.read() - d = cPickle.loads(raw) if raw.strip() else {} + d = {} + if os.path.exists(self.file_path): + with ExclusiveFile(self.file_path) as f: + raw = f.read() + d = cPickle.loads(raw) if raw.strip() else {} dict.__init__(self, d) def __getitem__(self, key): @@ -432,6 +497,8 @@ class DynamicConfig(dict): def commit(self): if hasattr(self, 'file_path') and self.file_path: + if not os.path.exists(self.file_path): + make_config_dir() with ExclusiveFile(self.file_path) as f: raw = cPickle.dumps(self, -1) f.seek(0) @@ -453,6 +520,12 @@ def _prefs(): help=_('Default timeout for network operations (seconds)')) c.add_opt('library_path', default=None, help=_('Path to directory in which your library of books is stored')) + c.add_opt('language', default=None, + help=_('The language in which to display the user interface')) + c.add_opt('output_format', default='LRF', + help=_('The default output format for ebook conversions.')) + c.add_opt('read_file_metadata', default=True, + help=_('Read metadata from files')) c.add_opt('migrated', default=False, help='For Internal use. Don\'t modify.') return c @@ -460,6 +533,8 @@ def _prefs(): prefs = ConfigProxy(_prefs()) def migrate(): + if hasattr(os, 'geteuid') and os.geteuid() == 0: + return p = prefs if p.get('migrated'): return @@ -546,4 +621,4 @@ if __name__ == '__main__': opts = c.parse() for i in ('one', 'two', 'three', 'four'): print i, repr(getattr(opts, i)) - \ No newline at end of file + diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index de966b14c9..bcd30068e8 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -73,6 +73,10 @@ MAP = { u"ь" : u"'", } #: Translation table +for c in string.whitespace: + MAP[c] = ' ' +PAT = re.compile('['+u''.join(MAP.keys())+']') + def ascii_filename(orig): orig = PAT.sub(lambda m:MAP[m.group()], orig) buf = [] diff --git a/src/calibre/utils/fontconfig.py b/src/calibre/utils/fontconfig.py index 93ee9f6566..9a6ba01992 100644 --- a/src/calibre/utils/fontconfig.py +++ b/src/calibre/utils/fontconfig.py @@ -151,7 +151,7 @@ class FontScanner(Thread): def run(self): # Initialize the fontconfig library. This has to be done manually # for the OS X bundle as it may have its own private fontconfig. - if getattr(sys, 'frameworks_dir', False) and not os.path.exists('/usr/X11/lib/libfontconfig.1.dylib'): + if getattr(sys, 'frameworks_dir', False):# and not os.path.exists('/usr/X11/lib/libfontconfig.1.dylib'): config_dir = os.path.join(os.path.dirname(getattr(sys, 'frameworks_dir')), 'Resources', 'fonts') if isinstance(config_dir, unicode): config_dir = config_dir.encode(sys.getfilesystemencoding()) diff --git a/src/calibre/utils/genshi/template/base.py b/src/calibre/utils/genshi/template/base.py index 64dc08fcdd..5a675f087c 100644 --- a/src/calibre/utils/genshi/template/base.py +++ b/src/calibre/utils/genshi/template/base.py @@ -513,6 +513,9 @@ class Template(object): value = [x for x in values if x is not None] if not value: continue + for i, v in enumerate(value): + if isinstance(v, str): + value[i] = v.decode('utf-8') new_attrs.append((name, u''.join(value))) yield kind, (tag, Attrs(new_attrs)), pos diff --git a/src/calibre/utils/threadpool.py b/src/calibre/utils/threadpool.py index 19b1a7b038..e2a5583baf 100644 --- a/src/calibre/utils/threadpool.py +++ b/src/calibre/utils/threadpool.py @@ -46,7 +46,6 @@ __date__ = "$Date: 2006/06/23 12:32:25 $" __license__ = 'Python license' # standard library modules -import sys import threading import Queue diff --git a/src/calibre/utils/windows/Makefile b/src/calibre/utils/windows/Makefile index 7507dee734..6e2dc51a7e 100644 --- a/src/calibre/utils/windows/Makefile +++ b/src/calibre/utils/windows/Makefile @@ -2,7 +2,8 @@ # Invoke with nmake /f Makefile.winutil test : winutil.pyd - python.exe -c "import winutil; winutil.set_debug(True); print winutil.get_usb_devices(); print winutil.get_mounted_volumes_for_usb_device(0x054c, 0x031e)" + python.exe -c "import winutil; winutil.set_debug(True); print repr(winutil.strftime(u'%b %a %A')); " +#python.exe -c "import winutil; winutil.set_debug(True); print winutil.get_usb_devices(); print winutil.get_mounted_volumes_for_usb_device(0x054c, 0x031e)" winutil.pyd : winutil.obj link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:c:\Python25\libs \ diff --git a/src/calibre/utils/windows/winutil.c b/src/calibre/utils/windows/winutil.c index 3be91cdb93..3388ba557b 100644 --- a/src/calibre/utils/windows/winutil.c +++ b/src/calibre/utils/windows/winutil.c @@ -57,12 +57,19 @@ wherever possible in this module. #define UNICODE #include <Windows.h> #include <Python.h> +#include <structseq.h> +#include <timefuncs.h> #include <shlobj.h> #include <stdio.h> #include <setupapi.h> #include <devguid.h> #include <cfgmgr32.h> #include <stdarg.h> +#include <time.h> + +#define PyStructSequence_GET_ITEM(op, i) \ + (((PyStructSequence *)(op))->ob_item[i]) + #define BUFSIZE 512 #define MAX_DRIVES 26 @@ -108,21 +115,17 @@ static PyObject * winutil_argv(PyObject *self, PyObject *args) { PyObject *argv, *v; LPWSTR *_argv; - LPSTR buf; - int argc, i, bytes; + int argc, i; if (!PyArg_ParseTuple(args, "")) return NULL; - _argv = CommandLineToArgvW(GetCommandLine(), &argc); + _argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (_argv == NULL) { PyErr_NoMemory(); return NULL; } argv = PyList_New(argc); if (argv != NULL) { for (i = 0; i < argc; i++) { - bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL); - buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes); - if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; } - WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL); - v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict"); - PyMem_Free(buf); - if (v == NULL) { Py_DECREF(argv); argv = NULL; break; } + v = PyUnicode_FromWideChar(_argv[i], wcslen(_argv[i])); + if ( v == NULL) { + Py_DECREF(argv); argv = NULL; PyErr_NoMemory(); break; + } PyList_SetItem(argv, i, v); } } @@ -130,6 +133,7 @@ winutil_argv(PyObject *self, PyObject *args) { return argv; } + static LPVOID format_last_error() { /* Format the last error as a string. The returned pointer should @@ -515,6 +519,137 @@ winutil_is_usb_device_connected(PyObject *self, PyObject *args) { return ans; } +static int +gettmarg(PyObject *args, struct tm *p) +{ + int y; + memset((void *) p, '\0', sizeof(struct tm)); + + if (!PyArg_Parse(args, "(iiiiiiiii)", + &y, + &p->tm_mon, + &p->tm_mday, + &p->tm_hour, + &p->tm_min, + &p->tm_sec, + &p->tm_wday, + &p->tm_yday, + &p->tm_isdst)) + return 0; + if (y < 1900) { + if (69 <= y && y <= 99) + y += 1900; + else if (0 <= y && y <= 68) + y += 2000; + else { + PyErr_SetString(PyExc_ValueError, + "year out of range"); + return 0; + } + } + p->tm_year = y - 1900; + p->tm_mon--; + p->tm_wday = (p->tm_wday + 1) % 7; + p->tm_yday--; + return 1; +} + +static PyObject * +winutil_strftime(PyObject *self, PyObject *args) +{ + PyObject *tup = NULL; + struct tm buf; + const char *_fmt; + size_t fmtlen, buflen; + wchar_t *outbuf = NULL, *fmt = NULL; + size_t i; + memset((void *) &buf, '\0', sizeof(buf)); + + if (!PyArg_ParseTuple(args, "s|O:strftime", &_fmt, &tup)) + return NULL; + fmtlen = mbstowcs(NULL, _fmt, strlen(_fmt)); + fmt = (wchar_t *)PyMem_Malloc((fmtlen+2)*sizeof(wchar_t)); + if (fmt == NULL) return PyErr_NoMemory(); + mbstowcs(fmt, _fmt, fmtlen+1); + + if (tup == NULL) { + time_t tt = time(NULL); + buf = *localtime(&tt); + } else if (!gettmarg(tup, &buf)) + goto end; + + if (buf.tm_mon == -1) + buf.tm_mon = 0; + else if (buf.tm_mon < 0 || buf.tm_mon > 11) { + PyErr_SetString(PyExc_ValueError, "month out of range"); + goto end; + } + if (buf.tm_mday == 0) + buf.tm_mday = 1; + else if (buf.tm_mday < 0 || buf.tm_mday > 31) { + PyErr_SetString(PyExc_ValueError, "day of month out of range"); + goto end; + } + if (buf.tm_hour < 0 || buf.tm_hour > 23) { + PyErr_SetString(PyExc_ValueError, "hour out of range"); + goto end; + } + if (buf.tm_min < 0 || buf.tm_min > 59) { + PyErr_SetString(PyExc_ValueError, "minute out of range"); + goto end; + } + if (buf.tm_sec < 0 || buf.tm_sec > 61) { + PyErr_SetString(PyExc_ValueError, "seconds out of range"); + goto end; + } + /* tm_wday does not need checking of its upper-bound since taking + ``% 7`` in gettmarg() automatically restricts the range. */ + if (buf.tm_wday < 0) { + PyErr_SetString(PyExc_ValueError, "day of week out of range"); + goto end; + } + if (buf.tm_yday == -1) + buf.tm_yday = 0; + else if (buf.tm_yday < 0 || buf.tm_yday > 365) { + PyErr_SetString(PyExc_ValueError, "day of year out of range"); + goto end; + } + if (buf.tm_isdst < -1 || buf.tm_isdst > 1) { + PyErr_SetString(PyExc_ValueError, + "daylight savings flag out of range"); + goto end; + } + + for (i = 5*fmtlen; ; i += i) { + outbuf = (wchar_t *)PyMem_Malloc(i*sizeof(wchar_t)); + if (outbuf == NULL) { + PyErr_NoMemory(); goto end; + } + buflen = wcsftime(outbuf, i, fmt, &buf); + if (buflen > 0 || i >= 256 * fmtlen) { + /* If the buffer is 256 times as long as the format, + it's probably not failing for lack of room! + More likely, the format yields an empty result, + e.g. an empty format, or %Z when the timezone + is unknown. */ + PyObject *ret; + ret = PyUnicode_FromWideChar(outbuf, buflen); + PyMem_Free(outbuf); PyMem_Free(fmt); + return ret; + } + PyMem_Free(outbuf); +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + /* VisualStudio .NET 2005 does this properly */ + if (buflen == 0 && errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + goto end; + } +#endif + } +end: + PyMem_Free(fmt); return NULL; +} + static PyMethodDef WinutilMethods[] = { {"special_folder_path", winutil_folder_path, METH_VARARGS, @@ -553,6 +688,15 @@ static PyMethodDef WinutilMethods[] = { "set_debug(bool)\n\nSet debugging mode." }, + {"strftime", winutil_strftime, METH_VARARGS, + "strftime(format[, tuple]) -> string\n\ +\n\ +Convert a time tuple to a string according to a format specification.\n\ +See the library reference manual for formatting codes. When the time tuple\n\ +is not present, current time as returned by localtime() is used. format must\n\ +be a unicode string. Returns unicode strings." + }, + {NULL, NULL, 0, NULL} }; diff --git a/src/calibre/utils/zipfile.py b/src/calibre/utils/zipfile.py index ff9eacf158..81c2e98f5a 100644 --- a/src/calibre/utils/zipfile.py +++ b/src/calibre/utils/zipfile.py @@ -2,6 +2,8 @@ Read and write ZIP files. Modified by Kovid Goyal to support replacing files in a zip archive. """ +from __future__ import with_statement +from calibre.ptempfile import TemporaryDirectory import struct, os, time, sys, shutil import binascii, cStringIO @@ -653,10 +655,10 @@ class ZipFile: fp = None # Set here since __del__ checks it - def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): + def __init__(self, file, mode="r", compression=ZIP_DEFLATED, allowZip64=False): """Open the ZIP file with mode read "r", write "w" or append "a".""" if mode not in ("r", "w", "a"): - raise RuntimeError('ZipFile() requires mode "r", "w", or "a"') + raise RuntimeError('ZipFile() requires mode "r", "w", or "a" not %s'%mode) if compression == ZIP_STORED: pass @@ -856,7 +858,8 @@ class ZipFile: if self.filelist[j].header_offset > deleted_offset: self.filelist[j].header_offset -= deleted_size if self.filelist[j].file_offset > deleted_offset: - self.filelist[j].file_offset -= deleted_size + self.filelist[j].file_offset -= deleted_size + self._didModify = True return if self.debug: print name, "not in archive" @@ -1034,10 +1037,11 @@ class ZipFile: os.makedirs(upperdirs) source = self.open(member, pwd=pwd) - target = open(targetpath, "wb") - shutil.copyfileobj(source, target) - source.close() - target.close() + if not os.path.exists(targetpath): # Could be a previously automatically created directory + target = open(targetpath, "wb") + shutil.copyfileobj(source, target) + source.close() + target.close() return targetpath @@ -1067,6 +1071,8 @@ class ZipFile: def write(self, filename, arcname=None, compress_type=None): """Put the bytes from filename into the archive under the name arcname.""" + if isinstance(filename, unicode): + filename = filename.encode('utf-8') if not self.fp: raise RuntimeError( "Attempt to write to ZIP archive that was already closed") @@ -1133,15 +1139,17 @@ class ZipFile: self.filelist.append(zinfo) self.NameToInfo[zinfo.filename] = zinfo - def writestr(self, zinfo_or_arcname, bytes): + def writestr(self, zinfo_or_arcname, bytes, permissions=0600, compression=ZIP_DEFLATED): """Write a file into the archive. The contents is the string 'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or the name of the file in the archive.""" if not isinstance(zinfo_or_arcname, ZipInfo): + if isinstance(zinfo_or_arcname, unicode): + zinfo_or_arcname = zinfo_or_arcname.encode('utf-8') zinfo = ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())[:6]) - zinfo.compress_type = self.compression - zinfo.external_attr = 0600 << 16 + zinfo.compress_type = compression + zinfo.external_attr = permissions << 16 else: zinfo = zinfo_or_arcname @@ -1171,6 +1179,26 @@ class ZipFile: zinfo.file_size)) self.filelist.append(zinfo) self.NameToInfo[zinfo.filename] = zinfo + + def add_dir(self, path, prefix=''): + ''' + Add a directory recursively to the zip file with an optional prefix. + ''' + if prefix: + self.writestr(prefix+'/', '', 0700) + cwd = os.path.abspath(os.getcwd()) + try: + os.chdir(path) + fp = (prefix + ('/' if prefix else '')).replace('//', '/') + for f in os.listdir('.'): + arcname = fp + f + if os.path.isdir(f): + self.add_dir(f, prefix=arcname) + else: + self.write(f, arcname) + finally: + os.chdir(cwd) + def __del__(self): """Call the "close()" method in case the user forgot.""" @@ -1281,6 +1309,32 @@ class ZipFile: self.fp.close() self.fp = None +def safe_replace(zipstream, name, datastream): + ''' + Replace a file in a zip file in a safe manner. This proceeds by extracting + and re-creating the zipfile. This is neccessary because :method:`ZipFile.replace` + sometimes created corrupted zip files. + + :param zipstream: Stream from a zip file + :param name: The name of the file to replace + :param datastream: The data to replace the file with. + ''' + z = ZipFile(zipstream, 'r') + names = z.namelist() + with TemporaryDirectory('_zipfile_replace') as tdir: + z.extractall(path=tdir) + zipstream.seek(0) + zipstream.truncate() + z = ZipFile(zipstream, 'w') + path = os.path.join(tdir, *name.split('/')) + shutil.copyfileobj(datastream, open(path, 'wb')) + for name in names: + current = os.path.join(tdir, *name.split('/')) + if os.path.isdir(current): + z.writestr(name+'/', '', 0700) + else: + z.write(current, name) + z.close() class PyZipFile(ZipFile): """Class to create ZIP archives with Python library files and packages.""" diff --git a/src/calibre/web/feeds/__init__.py b/src/calibre/web/feeds/__init__.py index 003e9af318..dffb9f8c56 100644 --- a/src/calibre/web/feeds/__init__.py +++ b/src/calibre/web/feeds/__init__.py @@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' ''' Contains the logic for parsing feeds. ''' -import time, logging, traceback +import time, logging, traceback, copy from datetime import datetime from calibre.web.feeds.feedparser import parse @@ -17,7 +17,7 @@ class Article(object): def __init__(self, id, title, url, summary, published, content): self.downloaded = False self.id = id - self.title = title + self.title = title.strip() if title else title self.url = url self.summary = summary self.content = content @@ -38,7 +38,14 @@ Has content : %s def __str__(self): return repr(self) - + + def is_same_as(self, other_article): + #if self.title != getattr(other_article, 'title', False): + # return False + if self.url: + return self.url == getattr(other_article, 'url', False) + return self.content == getattr(other_article, 'content', False) + class Feed(object): @@ -169,7 +176,72 @@ class Feed(object): len(a.summary if a.summary else '')) return length > 2000 * len(self) + + def has_article(self, article): + for a in self: + if a.is_same_as(article): + return True + return False + + def find(self, article): + for i, a in enumerate(self): + if a.is_same_as(article): + return i + return -1 + + def remove(self, article): + i = self.index(article) + if i > -1: + self.articles[i:i+1] = [] +class FeedCollection(list): + + def __init__(self, feeds): + list.__init__(self, [f for f in feeds if len(f.articles) > 0]) + found_articles = set([]) + duplicates = set([]) + + def in_set(s, a): + for x in s: + if a.is_same_as(x): + return x + return None + + print '#feeds', len(self) + print map(len, self) + for f in self: + dups = [] + for a in f: + first = in_set(found_articles, a) + if first is not None: + dups.append(a) + duplicates.add((first, f)) + else: + found_articles.add(a) + for x in dups: + f.articles.remove(x) + + self.duplicates = duplicates + print len(duplicates) + print map(len, self) + #raise + + def find_article(self, article): + for j, f in enumerate(self): + for i, a in enumerate(f): + if a is article: + return (j, i) + + def restore_duplicates(self): + temp = [] + for article, feed in self.duplicates: + art = copy.deepcopy(article) + j, i = self.find_article(article) + art.url = '../feed_%d/article_%d/index.html'%(j, i) + temp.append((feed, art)) + for feed, art in temp: + feed.articles.append(art) + def feed_from_xml(raw_xml, title=None, oldest_article=7, max_articles_per_feed=100, get_article_url=lambda item: item.get('link', None)): diff --git a/src/calibre/web/feeds/feedparser.py b/src/calibre/web/feeds/feedparser.py index f2b0ee74e9..a80670555a 100755 --- a/src/calibre/web/feeds/feedparser.py +++ b/src/calibre/web/feeds/feedparser.py @@ -1452,7 +1452,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser): # thanks to Kevin Marks for this breathtaking hack to deal with (valid) high-bit attribute values in UTF-8 feeds for key, value in attrs: if type(value) != type(u''): - value = unicode(value, self.encoding) + value = unicode(value, self.encoding, 'replace') uattrs.append((unicode(key, self.encoding), value)) strattrs = u''.join([u' %s="%s"' % (key, value) for key, value in uattrs]).encode(self.encoding) if tag in self.elements_no_end_tag: diff --git a/src/calibre/web/feeds/main.py b/src/calibre/web/feeds/main.py index 14299abecd..d56256de08 100644 --- a/src/calibre/web/feeds/main.py +++ b/src/calibre/web/feeds/main.py @@ -10,9 +10,56 @@ from calibre.web.feeds.recipes import get_builtin_recipe, compile_recipe, titles from calibre.web.fetch.simple import option_parser as _option_parser from calibre.web.feeds.news import Profile2Recipe, BasicNewsRecipe from calibre.ebooks.lrf.web.profiles import DefaultProfile, FullContentProfile +from calibre.utils.config import Config, StringConfig - -def option_parser(usage=_('''\ +def config(defaults=None): + desc = _('Options to control the fetching of periodical content from the web.') + c = Config('feeds2disk', desc) if defaults is None else StringConfig(defaults, desc) + + web2disk = c.add_group('web2disk', _('Customize the download engine')) + web2disk('timeout', ['-t', '--timeout'], default=10.0, + help=_('Timeout in seconds to wait for a response from the server. Default: %default s'),) + web2disk('delay', ['--delay'], default=0, + help=_('Minimum interval in seconds between consecutive fetches. Default is %default s')) + web2disk('encoding', ['--encoding'], default=None, + help=_('The character encoding for the websites you are trying to download. The default is to try and guess the encoding.')) + web2disk('match_regexps', ['--match-regexp'], default=[], action='append', + help=_('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.')) + web2disk('filter_regexps', ['--filter-regexp'], default=[], action='append', + help=_('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.')) + web2disk('no_stylesheets', ['--dont-download-stylesheets'], action='store_true', default=False, + help=_('Do not download CSS stylesheets.')) + + c.add_opt('feeds', ['--feeds'], default=None, + help=_('''Specify a list of feeds to download. For example: +"['http://feeds.newsweek.com/newsweek/TopNews', 'http://feeds.newsweek.com/headlines/politics']" +If you specify this option, any argument to %prog is ignored and a default recipe is used to download the feeds.''')) + c.add_opt('verbose', ['-v', '--verbose'], default=0, action='count', + help=_('''Be more verbose while processing.''')) + c.add_opt('title', ['--title'], default=None, + help=_('The title for this recipe. Used as the title for any ebooks created from the downloaded feeds.')) + c.add_opt('username', ['-u', '--username'], default=None, + help=_('Username for sites that require a login to access content.')) + c.add_opt('password', ['-p', '--password'], default=None, + help=_('Password for sites that require a login to access content.')) + c.add_opt('lrf', ['--lrf'], default=False, action='store_true', + help='Optimize fetching for subsequent conversion to LRF.') + c.add_opt('epub', ['--epub'], default=False, action='store_true', + help='Optimize fetching for subsequent conversion to EPUB.') + c.add_opt('recursions', ['--recursions'], default=0, + help=_('Number of levels of links to follow on webpages that are linked to from feeds. Defaul %default')) + c.add_opt('output_dir', ['--output-dir'], default='.', + help=_('The directory in which to store the downloaded feeds. Defaults to the current directory.')) + c.add_opt('no_progress_bar', ['--no-progress-bar'], default=False, action='store_true', + help=_("Don't show the progress bar")) + c.add_opt('debug', ['--debug'], action='store_true', default=False, + help=_('Very verbose output, useful for debugging.')) + c.add_opt('test', ['--test'], action='store_true', default=False, + help=_('Useful for recipe development. Forces max_articles_per_feed to 2 and downloads at most 2 feeds.')) + + return c + +USAGE=_('''\ %%prog [options] ARG %%prog parses an online source of articles, like an RSS or ATOM feed and @@ -28,7 +75,9 @@ recipe as a string - %%prog will load the recipe directly from the string arg. Available builtin recipes are: %s -''')%(unicode(list(titles))[1:-1])): +''')%(unicode(list(titles))[1:-1]) + +def option_parser(usage=USAGE): p = _option_parser(usage=usage) p.remove_option('--max-recursions') p.remove_option('--base-dir') @@ -51,7 +100,7 @@ If you specify this option, any argument to %prog is ignored and a default recip help=_('Number of levels of links to follow on webpages that are linked to from feeds. Defaul %default')) p.add_option('--output-dir', default=os.getcwd(), help=_('The directory in which to store the downloaded feeds. Defaults to the current directory.')) - p.add_option('--no-progress-bar', dest='progress_bar', default=True, action='store_false', + p.add_option('--no-progress-bar', dest='no_progress_bar', default=False, action='store_true', help=_('Dont show the progress bar')) p.add_option('--debug', action='store_true', default=False, help=_('Very verbose output, useful for debugging.')) @@ -67,7 +116,7 @@ def run_recipe(opts, recipe_arg, parser, notification=None, handler=None): if notification is None: from calibre.utils.terminfo import TerminalController, ProgressBar term = TerminalController(sys.stdout) - pb = ProgressBar(term, _('Fetching feeds...'), no_progress_bar=not opts.progress_bar) + pb = ProgressBar(term, _('Fetching feeds...'), no_progress_bar=opts.no_progress_bar) notification = pb.update recipe, is_profile = None, False @@ -76,14 +125,9 @@ def run_recipe(opts, recipe_arg, parser, notification=None, handler=None): else: try: if os.access(recipe_arg, os.R_OK): - try: - recipe = compile_recipe(open(recipe_arg).read()) - is_profile = DefaultProfile in recipe.__bases__ or \ - FullContentProfile in recipe.__bases__ - except: - import traceback - traceback.print_exc() - return 1 + recipe = compile_recipe(open(recipe_arg).read()) + is_profile = DefaultProfile in recipe.__bases__ or \ + FullContentProfile in recipe.__bases__ else: raise Exception('not file') except: diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 530f15b9ab..212ca84aac 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' ''' @@ -10,6 +10,7 @@ __docformat__ = "restructuredtext en" import logging, os, cStringIO, time, traceback, re, urlparse, sys from collections import defaultdict from functools import partial +from contextlib import nested, closing from calibre import browser, __appname__, iswindows, LoggingInterface, strftime from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString, CData, Tag @@ -17,7 +18,7 @@ from calibre.ebooks.metadata.opf import OPFCreator from calibre.ebooks.lrf import entity_to_unicode from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.metadata import MetaInformation -from calibre.web.feeds import feed_from_xml, templates, feeds_from_index +from calibre.web.feeds import feed_from_xml, templates, feeds_from_index, Feed from calibre.web.fetch.simple import option_parser as web2disk_option_parser from calibre.web.fetch.simple import RecursiveFetcher from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending @@ -137,6 +138,9 @@ class BasicNewsRecipe(object, LoggingInterface): #: List of options to pass to html2lrf, to customize generation of LRF ebooks. html2lrf_options = [] + #: Options to pass to html2epub to customize generation of EPUB ebooks. + html2epub_options = '' + #: List of tags to be removed. Specified tags are removed from downloaded HTML. #: A tag is specified as a dictionary of the form:: #: @@ -285,15 +289,16 @@ class BasicNewsRecipe(object, LoggingInterface): ''' return soup - def postprocess_html(self, soup): + def postprocess_html(self, soup, first_fetch): ''' This method is called with the source of each downloaded :term:`HTML` file, after it is parsed for links and images. It can be used to do arbitrarily powerful post-processing on the :term:`HTML`. It should return `soup` after processing it. - `soup`: A `BeautifulSoup <http://www.crummy.com/software/BeautifulSoup/documentation.html>`_ + :param soup: A `BeautifulSoup <http://www.crummy.com/software/BeautifulSoup/documentation.html>`_ instance containing the downloaded :term:`HTML`. + :param first_fetch: True if this is the first page of an article. ''' return soup @@ -313,7 +318,9 @@ class BasicNewsRecipe(object, LoggingInterface): `url_or_raw`: Either a URL or the downloaded index page as a string ''' if re.match(r'\w+://', url_or_raw): - raw = self.browser.open(url_or_raw).read() + f = self.browser.open(url_or_raw) + raw = f.read() + f.close() if not raw: raise RuntimeError('Could not fetch index from %s'%url_or_raw) else: @@ -407,7 +414,7 @@ class BasicNewsRecipe(object, LoggingInterface): defaults = parser.get_default_values() for opt in options.__dict__.keys(): - if getattr(options, opt) != getattr(defaults, opt): + if getattr(options, opt) != getattr(defaults, opt, None): setattr(self, opt, getattr(options, opt)) if isinstance(self.feeds, basestring): @@ -476,7 +483,7 @@ class BasicNewsRecipe(object, LoggingInterface): elem = BeautifulSoup(templ.render(doctype='xhtml').decode('utf-8')).find('div') body.insert(0, elem) - return self.postprocess_html(soup) + return self.postprocess_html(soup, first_fetch) def download(self): @@ -487,25 +494,27 @@ class BasicNewsRecipe(object, LoggingInterface): @return: Path to index.html @rtype: string ''' - res = self.build_index() - self.cleanup() - self.report_progress(1, _('Download finished')) - if self.failed_downloads: - self.log_warning(_('Failed to download the following articles:')) - for feed, article, debug in self.failed_downloads: - self.log_warning(article.title+_(' from ')+feed.title) - self.log_debug(article.url) - self.log_debug(debug) - if self.partial_failures: - self.log_warning(_('Failed to download parts of the following articles:')) - for feed, atitle, aurl, debug in self.partial_failures: - self.log_warning(atitle + _(' from ') + feed) - self.log_debug(aurl) - self.log_warning(_('\tFailed links:')) - for l, tb in debug: - self.log_warning(l) - self.log_debug(tb) - return res + try: + res = self.build_index() + self.report_progress(1, _('Download finished')) + if self.failed_downloads: + self.log_warning(_('Failed to download the following articles:')) + for feed, article, debug in self.failed_downloads: + self.log_warning(article.title+_(' from ')+feed.title) + self.log_debug(article.url) + self.log_debug(debug) + if self.partial_failures: + self.log_warning(_('Failed to download parts of the following articles:')) + for feed, atitle, aurl, debug in self.partial_failures: + self.log_warning(atitle + _(' from ') + feed) + self.log_debug(aurl) + self.log_warning(_('\tFailed links:')) + for l, tb in debug: + self.log_warning(l) + self.log_debug(tb) + return res + finally: + self.cleanup() def feeds2index(self, feeds): templ = templates.IndexTemplate() @@ -544,7 +553,8 @@ class BasicNewsRecipe(object, LoggingInterface): if bn: img = os.path.join(imgdir, 'feed_image_%d%s'%(self.image_counter, os.path.splitext(bn))) try: - open(img, 'wb').write(self.browser.open(feed.image_url).read()) + with nested(open(img, 'wb'), closing(self.browser.open(feed.image_url))) as (fi, r): + fi.write(r.read()) self.image_counter += 1 feed.image_url = img self.image_map[feed.image_url] = img @@ -588,12 +598,11 @@ class BasicNewsRecipe(object, LoggingInterface): return self._fetch_article(url, dir, logger, f, a, num_of_feeds) def fetch_embedded_article(self, article, dir, logger, f, a, num_of_feeds): - pt = PersistentTemporaryFile('_feeds2disk.html') templ = templates.EmbeddedContent() raw = templ.generate(article).render('html') - open(pt.name, 'wb').write(raw) - pt.close() - url = ('file:'+pt.name) if iswindows else ('file://'+pt.name) + with PersistentTemporaryFile('_feeds2disk.html') as pt: + pt.write(raw) + url = ('file:'+pt.name) if iswindows else ('file://'+pt.name) return self._fetch_article(url, dir, logger, f, a, num_of_feeds) @@ -606,6 +615,8 @@ class BasicNewsRecipe(object, LoggingInterface): except NotImplementedError: feeds = self.parse_feeds() + #feeds = FeedCollection(feeds) + self.report_progress(0, _('Trying to download cover...')) self.download_cover() if self.test: @@ -618,7 +629,8 @@ class BasicNewsRecipe(object, LoggingInterface): index = os.path.join(self.output_dir, 'index.html') html = self.feeds2index(feeds) - open(index, 'wb').write(html) + with open(index, 'wb') as fi: + fi.write(html) self.jobs = [] for f, feed in enumerate(feeds): @@ -639,7 +651,6 @@ class BasicNewsRecipe(object, LoggingInterface): url = article.url if not url: continue - func, arg = (self.fetch_embedded_article, article) if self.use_embedded_content else \ ((self.fetch_obfuscated_article if self.articles_are_obfuscated \ else self.fetch_article), url) @@ -667,10 +678,13 @@ class BasicNewsRecipe(object, LoggingInterface): except NoResultsPending: break + #feeds.restore_duplicates() + for f, feed in enumerate(feeds): html = self.feed2index(feed) feed_dir = os.path.join(self.output_dir, 'feed_%d'%f) - open(os.path.join(feed_dir, 'index.html'), 'wb').write(html) + with open(os.path.join(feed_dir, 'index.html'), 'wb') as fi: + fi.write(html) self.create_opf(feeds) self.report_progress(1, _('Feeds downloaded to %s')%index) @@ -689,8 +703,8 @@ class BasicNewsRecipe(object, LoggingInterface): ext = ext.lower() if ext else 'jpg' self.report_progress(1, _('Downloading cover from %s')%cu) cpath = os.path.join(self.output_dir, 'cover.'+ext) - cfile = open(cpath, 'wb') - cfile.write(self.browser.open(cu).read()) + with nested(open(cpath, 'wb'), closing(self.browser.open(cu))) as (cfile, r): + cfile.write(r.read()) self.cover_path = cpath @@ -714,6 +728,8 @@ class BasicNewsRecipe(object, LoggingInterface): entries = ['index.html'] toc = TOC(base_path=dir) + self.play_order_counter = 0 + self.play_order_map = {} def feed_index(num, parent): f = feeds[num] @@ -721,7 +737,12 @@ class BasicNewsRecipe(object, LoggingInterface): if getattr(a, 'downloaded', False): adir = 'feed_%d/article_%d/'%(num, j) entries.append('%sindex.html'%adir) - parent.add_item('%sindex.html'%adir, None, a.title if a.title else _('Untitled Article')) + po = self.play_order_map.get(entries[-1], None) + if po is None: + self.play_order_counter += 1 + po = self.play_order_counter + parent.add_item('%sindex.html'%adir, None, a.title if a.title else _('Untitled Article'), + play_order=po) last = os.path.join(self.output_dir, ('%sindex.html'%adir).replace('/', os.sep)) for sp in a.sub_pages: prefix = os.path.commonprefix([opf_path, sp]) @@ -729,23 +750,30 @@ class BasicNewsRecipe(object, LoggingInterface): entries.append(relp.replace(os.sep, '/')) last = sp - src = open(last, 'rb').read().decode('utf-8') - soup = BeautifulSoup(src) - body = soup.find('body') - if body is not None: - prefix = '/'.join('..'for i in range(2*len(re.findall(r'link\d+', last)))) - templ = self.navbar.generate(True, num, j, len(f), - not self.has_single_feed, - a.orig_url, __appname__, prefix=prefix, - center=self.center_navbar) - elem = BeautifulSoup(templ.render(doctype='xhtml').decode('utf-8')).find('div') - body.insert(len(body.contents), elem) - open(last, 'wb').write(unicode(soup).encode('utf-8')) + if os.path.exists(last): + with open(last, 'rb') as fi: + src = fi.read().decode('utf-8') + soup = BeautifulSoup(src) + body = soup.find('body') + if body is not None: + prefix = '/'.join('..'for i in range(2*len(re.findall(r'link\d+', last)))) + templ = self.navbar.generate(True, num, j, len(f), + not self.has_single_feed, + a.orig_url, __appname__, prefix=prefix, + center=self.center_navbar) + elem = BeautifulSoup(templ.render(doctype='xhtml').decode('utf-8')).find('div') + body.insert(len(body.contents), elem) + with open(last, 'wb') as fi: + fi.write(unicode(soup).encode('utf-8')) if len(feeds) > 1: for i, f in enumerate(feeds): entries.append('feed_%d/index.html'%i) - feed_index(i, toc.add_item('feed_%d/index.html'%i, None, f.title)) + po = self.play_order_map.get(entries[-1], None) + if po is None: + self.play_order_counter += 1 + po = self.play_order_counter + feed_index(i, toc.add_item('feed_%d/index.html'%i, None, f.title, play_order=po)) else: entries.append('feed_%d/index.html'%0) feed_index(0, toc) @@ -755,7 +783,8 @@ class BasicNewsRecipe(object, LoggingInterface): opf.create_spine(entries) opf.set_toc(toc) - opf.render(open(opf_path, 'wb'), open(ncx_path, 'wb')) + with nested(open(opf_path, 'wb'), open(ncx_path, 'wb')) as (opf_file, ncx_file): + opf.render(opf_file, ncx_file) def article_downloaded(self, request, result): @@ -800,12 +829,21 @@ class BasicNewsRecipe(object, LoggingInterface): else: title, url = obj self.report_progress(0, _('Fetching feed')+' %s...'%(title if title else url)) - parsed_feeds.append(feed_from_xml(self.browser.open(url).read(), - title=title, - oldest_article=self.oldest_article, - max_articles_per_feed=self.max_articles_per_feed, - get_article_url=self.get_article_url)) - + try: + with closing(self.browser.open(url)) as f: + parsed_feeds.append(feed_from_xml(f.read(), + title=title, + oldest_article=self.oldest_article, + max_articles_per_feed=self.max_articles_per_feed, + get_article_url=self.get_article_url)) + except Exception, err: + feed = Feed() + msg = 'Failed feed: %s'%(title if title else url) + feed.populate_from_preparsed_feed(msg, []) + feed.description = unicode(err) + parsed_feeds.append(feed) + self.log_exception(msg) + return parsed_feeds @classmethod @@ -891,7 +929,8 @@ class CustomIndexRecipe(BasicNewsRecipe): mi = OPFCreator(self.output_dir, mi) mi.create_manifest_from_files_in([self.output_dir]) mi.create_spine([os.path.join(self.output_dir, 'index.html')]) - mi.render(open(os.path.join(self.output_dir, 'index.opf'), 'wb')) + with open(os.path.join(self.output_dir, 'index.opf'), 'wb') as opf_file: + mi.render(opf_file) def download(self): index = os.path.abspath(self.custom_index()) diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index ba09ff69bb..375996bf37 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -9,9 +9,11 @@ recipes = [ 'nytimes', 'usatoday', 'outlook_india', 'bbc', 'greader', 'wsj', 'wired', 'globe_and_mail', 'smh', 'espn', 'business_week', 'ars_technica', 'upi', 'new_yorker', 'irish_times', 'iht', + 'discover_magazine', 'scientific_american', 'new_york_review_of_books', + 'daily_telegraph', ] -import re, imp, inspect, time +import re, imp, inspect, time, os from calibre.web.feeds.news import BasicNewsRecipe, CustomIndexRecipe, AutomaticNewsRecipe from calibre.ebooks.lrf.web.profiles import DefaultProfile, FullContentProfile from calibre.ebooks.lrf.web import builtin_profiles @@ -54,7 +56,7 @@ def compile_recipe(src): @return: Recipe/Profile class or None, if no such class was found in C{src} ''' global _tdir, _crep - if _tdir is None: + if _tdir is None or not os.path.exists(_tdir): _tdir = path(PersistentTemporaryDirectory('_recipes')) temp = _tdir/('recipe%d.py'%_crep) _crep += 1 diff --git a/src/calibre/web/feeds/recipes/daily_telegraph.py b/src/calibre/web/feeds/recipes/daily_telegraph.py new file mode 100644 index 0000000000..dfad458276 --- /dev/null +++ b/src/calibre/web/feeds/recipes/daily_telegraph.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +http://www.news.com.au/dailytelegraph/ +''' +import re +from calibre.web.feeds.news import BasicNewsRecipe + +class DailyTelegraph(BasicNewsRecipe): + title = u'Daily Telegraph' + __author__ = u'AprilHare' + description = u'News from down under' + oldest_article = 2 + max_articles_per_feed = 10 + remove_tags_before = dict(name='div', attrs={'class':'article-title'}) + remove_tags = [dict(attrs={'class':['article-source', 'article-tools']})] + remove_tags_after = dict(attrs={'class':re.compile('share-article')}) + + feeds = [ + (u'Top Stories', u'http://feeds.news.com.au/public/rss/2.0/dtele_top_stories_253.xml'), + (u'National News', u'http://feeds.news.com.au/public/rss/2.0/dtele_national_news_202.xml'), + (u'World News', u'http://feeds.news.com.au/public/rss/2.0/dtele_world_news_204.xml'), + (u'NSW and ACT', u'http://feeds.news.com.au/public/rss/2.0/dtele_nswact_225.xml'), + (u'Arts', u'http://feeds.news.com.au/public/rss/2.0/dtele_art_444.xml'), + (u'Business News', u'http://feeds.news.com.au/public/rss/2.0/dtele_business_226.xml'), + (u'Entertainment News', u'http://feeds.news.com.au/public/rss/2.0/dtele_entertainment_news_201.xml'), + (u'Lifestyle News', u'http://feeds.news.com.au/public/rss/2.0/dtele_lifestyle_227.xml'), + (u'Music', u'http://feeds.news.com.au/public/rss/2.0/dtele_music_441.xml'), + (u'Property Confidential', u'http://feeds.news.com.au/public/rss/2.0/dtele_property_confidential_463.xml'), + (u'Property - Your Space', u'http://feeds.news.com.au/public/rss/2.0/dtele_property_yourspace_462.xml'), + (u'Confidential News', u'http://feeds.news.com.au/public/rss/2.0/dtele_entertainment_confidential_252.xml'), + (u'Confidential Biographies', u'http://feeds.news.com.au/public/rss/2.0/dtele_confidential_biographies_491.xml'), + (u'Confidential Galleries', u'http://feeds.news.com.au/public/rss/2.0/dtele_confidential_galleries_483.xml'), + (u'Confidential In-depth', u'http://feeds.news.com.au/public/rss/2.0/dtele_confidential_indepth_490.xml'), + (u'Confidential ShowBuzz', u'http://feeds.news.com.au/public/rss/2.0/dtele_confidential_showbuzz_485.xml'), + (u'Sport', u'http://feeds.news.com.au/public/rss/2.0/dtele_sport_203.xml'), + (u'AFL', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_afl_341.xml'), + (u'Cricket', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_cricket_343.xml'), + (u'Horse Racing', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_horseracing_686.xml'), + (u'NRL', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_nrl_345.xml'), + (u'Rugby Union', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_rugby_union_342.xml'), + (u'Soccer', u'http://feeds.news.com.au/public/rss/2.0/dtele_sports_soccer_344.xml') + ] \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/discover_magazine.py b/src/calibre/web/feeds/recipes/discover_magazine.py new file mode 100644 index 0000000000..0e3753834b --- /dev/null +++ b/src/calibre/web/feeds/recipes/discover_magazine.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +doscovermagazine.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class DiscoverMagazine(BasicNewsRecipe): + title = u'Discover Magazine' + description = u'Science, Technology and the Future' + __author__ = 'Mike Diaz' + oldest_article = 33 + max_articles_per_feed = 20 + feeds = [ + (u'Technology', u'http://discovermagazine.com/topics/technology/rss.xml'), + (u'Health - Medicine', u'http://discovermagazine.com/topics/health-medicine/rss.xml'), + (u'Mind Brain', u'http://discovermagazine.com/topics/mind-brain/rss.xml'), + (u'Space', u'http://discovermagazine.com/topics/space/rss.xml'), + (u'Human Origins', u'http://discovermagazine.com/topics/human-origins/rss.xml'), + (u'Living World', u'http://discovermagazine.com/topics/living-world/rss.xml'), + (u'Environment', u'http://discovermagazine.com/topics/environment/rss.xml'), + (u'Physics & Math', u'http://discovermagazine.com/topics/physics-math/rss.xml'), + (u'Vital Signs', u'http://discovermagazine.com/columns/vital-signs/rss.xml'), + (u"20 Things you didn't know about...", u'http://discovermagazine.com/columns/20-things-you-didnt-know/rss.xml'), + (u'Fuzzy Math', u'http://discovermagazine.com/columns/fuzzy-math/rss.xml'), + (u'The Brain', u'http://discovermagazine.com/columns/the-brain/rss.xml'), + (u'Stupid Science Word of the Month', u'http://discovermagazine.com/columns/stupid-science-word-of-the-month/rss.xml'), + (u'Science Not Fiction', u'http://blogs.discovermagazine.com/sciencenotfiction/wp-rss.php') + ] \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/economist.py b/src/calibre/web/feeds/recipes/economist.py index 8794886d21..3c75bd4237 100644 --- a/src/calibre/web/feeds/recipes/economist.py +++ b/src/calibre/web/feeds/recipes/economist.py @@ -33,14 +33,14 @@ class Economist(BasicNewsRecipe): return br def parse_index(self): - soup = BeautifulSoup(self.browser.open(self.INDEX).read(), + soup = BeautifulSoup(self.browser.open(self.INDEX).read(), convertEntities=BeautifulSoup.HTML_ENTITIES) index_started = False feeds = {} ans = [] key = None for tag in soup.findAll(['h1', 'h2']): - text = ''.join(tag.findAll(text=True)) + text = ''.join(tag.findAll(text=True)) if tag.name == 'h1': if 'Classified ads' in text: break diff --git a/src/calibre/web/feeds/recipes/espn.py b/src/calibre/web/feeds/recipes/espn.py index d8c33847cf..34a1bc609a 100644 --- a/src/calibre/web/feeds/recipes/espn.py +++ b/src/calibre/web/feeds/recipes/espn.py @@ -67,7 +67,7 @@ class ESPN(BasicNewsRecipe): return soup - def postprocess_html(self, soup): + def postprocess_html(self, soup, first_fetch): for div in soup.findAll('div', style=True): div['style'] = div['style'].replace('center', 'left') return soup diff --git a/src/calibre/web/feeds/recipes/new_york_review_of_books.py b/src/calibre/web/feeds/recipes/new_york_review_of_books.py new file mode 100644 index 0000000000..e2bb4e0960 --- /dev/null +++ b/src/calibre/web/feeds/recipes/new_york_review_of_books.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +nybooks.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe +from lxml import html +from calibre.constants import preferred_encoding + +class NewYorkReviewOfBooks(BasicNewsRecipe): + + title = u'New York Review of Books' + description = u'Book reviews' + __author__ = 'Kovid Goyal' + + remove_tags_before = {'id':'container'} + remove_tags = [{'class':['noprint', 'ad', 'footer']}, {'id':'right-content'}] + + def parse_index(self): + root = html.fromstring(self.browser.open('http://www.nybooks.com/current-issue').read()) + date = root.xpath('//h4[@class = "date"]')[0] + self.timefmt = ' ['+date.text.encode(preferred_encoding)+']' + articles = [] + for tag in date.itersiblings(): + if tag.tag == 'h4': break + if tag.tag == 'p': + if tag.get('class') == 'indented': + articles[-1]['description'] += html.tostring(tag) + else: + href = tag.xpath('descendant::a[@href]')[0].get('href') + article = { + 'title': u''.join(tag.xpath('descendant::text()')), + 'date' : '', + 'url' : 'http://www.nybooks.com'+href, + 'description': '', + } + articles.append(article) + + return [('Current Issue', articles)] + + + + + + + \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/new_yorker.py b/src/calibre/web/feeds/recipes/new_yorker.py index cdc6d8c0e3..ed9811c43b 100644 --- a/src/calibre/web/feeds/recipes/new_yorker.py +++ b/src/calibre/web/feeds/recipes/new_yorker.py @@ -3,7 +3,8 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' -import re, time +import re +from calibre import strftime from calibre.web.feeds.news import BasicNewsRecipe from calibre.ebooks.BeautifulSoup import NavigableString @@ -20,7 +21,7 @@ class NewYorker(BasicNewsRecipe): def parse_index(self): - toc_pat = re.compile(time.strftime(r'.+magazine/toc/%Y/%m/.+toc_%Y\d+')) + toc_pat = re.compile(r'/magazine/toc/\d+/\d+/\d+/toc_\d+') soup = self.soup(self.browser.open('http://www.newyorker.com/').read()) a = soup.find('a', href=toc_pat) if a is None: @@ -65,7 +66,7 @@ class NewYorker(BasicNewsRecipe): 'title': title, 'desc': desc, 'content':'', 'url': href, - 'date': time.strftime('%a, %d %b', time.localtime()), + 'date': strftime('%a, %d %b'), } articles.append(art) diff --git a/src/calibre/web/feeds/recipes/newsweek.py b/src/calibre/web/feeds/recipes/newsweek.py index cab07d974f..9ad551c469 100644 --- a/src/calibre/web/feeds/recipes/newsweek.py +++ b/src/calibre/web/feeds/recipes/newsweek.py @@ -3,6 +3,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' import re, string, time +from calibre import strftime from calibre.web.feeds.news import BasicNewsRecipe from calibre.ebooks.BeautifulSoup import BeautifulSoup @@ -68,7 +69,7 @@ class Newsweek(BasicNewsRecipe): small = img['src'] match = re.search(r'(\d+)_', small.rpartition('/')[-1]) if match is not None: - self.timefmt = time.strftime(' [%d %b, %Y]', time.strptime(match.group(1), '%y%m%d')) + self.timefmt = strftime(' [%d %b, %Y]', time.strptime(match.group(1), '%y%m%d')) self.cover_url = small.replace('coversmall', 'coverlarge') sections = self.get_sections(soup) @@ -84,14 +85,14 @@ class Newsweek(BasicNewsRecipe): 'title' : title, 'url' : a['href'], 'description':'', 'content':'', - 'date': time.strftime('%a, %d %b', time.localtime()) + 'date': strftime('%a, %d %b') } if art['title'] and art['url']: sections[0][1].append(art) return sections - def postprocess_html(self, soup): + def postprocess_html(self, soup, first_fetch): divs = list(soup.findAll('div', 'pagination')) if not divs: return diff --git a/src/calibre/web/feeds/recipes/nytimes.py b/src/calibre/web/feeds/recipes/nytimes.py index 3e1fca6279..17fe1b9b1b 100644 --- a/src/calibre/web/feeds/recipes/nytimes.py +++ b/src/calibre/web/feeds/recipes/nytimes.py @@ -5,7 +5,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' ''' nytimes.com ''' -import time, string +import string +from calibre import strftime from calibre.web.feeds.recipes import BasicNewsRecipe class NYTimes(BasicNewsRecipe): @@ -59,7 +60,7 @@ class NYTimes(BasicNewsRecipe): url = self.print_version(a['href']) title = self.tag_to_string(a, use_alt=True).strip() description = '' - pubdate = time.strftime('%a, %d %b', time.localtime()) + pubdate = strftime('%a, %d %b') summary = div.find(True, attrs={'class':'summary'}) if summary: description = self.tag_to_string(summary, use_alt=False) diff --git a/src/calibre/web/feeds/recipes/outlook_india.py b/src/calibre/web/feeds/recipes/outlook_india.py index c5782d1536..db8ad900ab 100644 --- a/src/calibre/web/feeds/recipes/outlook_india.py +++ b/src/calibre/web/feeds/recipes/outlook_india.py @@ -73,7 +73,7 @@ class OutlookIndia(BasicNewsRecipe): return feeds - def postprocess_html(self, soup): + def postprocess_html(self, soup, first_fetch): bad = [] for table in soup.findAll('table'): if table.find(text=re.compile(r'\(\d+ of \d+\)')): diff --git a/src/calibre/web/feeds/recipes/scientific_american.py b/src/calibre/web/feeds/recipes/scientific_american.py new file mode 100644 index 0000000000..468e799d44 --- /dev/null +++ b/src/calibre/web/feeds/recipes/scientific_american.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +sciam.com +''' +import re +from lxml import html +from calibre.web.feeds.news import BasicNewsRecipe + +class ScientificAmerican(BasicNewsRecipe): + title = u'Scientific American' + description = u'Popular science. Monthly magazine.' + __author__ = 'Kovid Goyal' + oldest_article = 30 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + remove_tags_before = dict(name='div', attrs={'class':'headline'}) + remove_tags_after = dict(id='article') + remove_tags = [ + dict(id=['sharetools', 'reddit']), + dict(name='script'), + {"class": re.compile(r'also-in-this')} + ] + html2lrf_options = ['--base-font-size', '8'] + recursions = 1 + match_regexps = [r'article.cfm.id=\S+page=(2|3|4|5|6|7|8|9|10|11|12|13|14)'] +# feeds = [ +# (u'Latest News', u'http://rss.sciam.com/ScientificAmerican-News'), +# (u'Global', u'http://rss.sciam.com/ScientificAmerican-Global'), +# (u'Health', u'http://rss.sciam.com/sciam/health'), +# (u'Space', u'http://rss.sciam.com/sciam/space'), +# (u'Technology', u'http://rss.sciam.com/sciam/technology'), +# (u'Biology', u'http://rss.sciam.com/sciam/biology'), +# (u'Mind & Brain', u'http://rss.sciam.com/sciam/mind-and-brain'), +# (u"What's Next", u'http://rss.sciam.com/sciam/whats-next'), +# (u'Archeology and Paleontology', u'http://www.sciam.com/page.cfm?section=rsscategory&alias=archaeology-and-paleontology'), +# (u'Physics', u'http://www.sciam.com/page.cfm?section=rsscategory&alias=physics'), +# (u'Math', u'http://rss.sciam.com/sciam/math'), +# (u'History of Science', u'http://www.sciam.com/page.cfm?section=rsscategory&alias=history-of-science'), +# (u'Chemistry', u'http://rss.sciam.com/sciam/chemistry'), +# (u'Mind Matters', u'http://rss.sciam.com/ScientificAmerican-MindBlog') +# ] +# + def parse_index(self): + src = self.browser.open('http://www.sciam.com/sciammag/').read() + root = html.fromstring(src) + self.cover_url = root.xpath('//img[re:match(@src, "cover_")]', + namespaces={'re':'http://exslt.org/regular-expressions'} + )[0].get('src') + self.timefmt = ' [%s]'%(root.xpath('//div[@id = "magazine-month"]')[0].text) + feeds = [] + features = [] + for a in root.xpath('//a[@href and @title = "Feature"]'): + if not a.text.strip(): + continue + article = { + 'url' : a.get('href'), + 'title' : u''.join(a.xpath('./text()')), + 'date' : '', + 'description' : '', + } + for s in a.itersiblings('span'): + if s.get('class', '') == 'sub': + article['description'] += u''.join(s.xpath('./text()')) + ' ' + features.append(article) + if features: + feeds.append(('Features', features)) + + departments = [] + for a in root.xpath('//a[@href and @class="title"]'): + txt = u''.join(a.xpath('./text()')).strip() + if not txt: + continue + article = { + 'url' : a.get('href'), + 'title' : txt, + 'date' : '', + 'description' : '', + } + p = a.getparent() + p.remove(a) + article['description'] = u''.join(p.xpath('./text()')) + departments.append(article) + + feeds.append(('Departments', departments)) + opinion = [] + for a in root.xpath('//div[@id = "opinion"]//a[@href]'): + txt = u''.join(a.xpath('./text()')).strip() + if not txt: + continue + article = { + 'url' : a.get('href'), + 'title' : txt, + 'date' : '', + 'description' : '', + } + opinion.append(article) + feeds.append(('Opinion', opinion)) + + ontheweb = [] + for a in root.xpath('//div[@id = "ontheweb"]//a[@href]'): + txt = u''.join(a.xpath('./text()')).strip() + if not txt: + continue + article = { + 'url' : a.get('href'), + 'title' : txt, + 'date' : '', + 'description' : '', + } + ontheweb.append(article) + feeds.append(('On the web', ontheweb)) + + return feeds + + + def postprocess_html(self, soup, first_fetch): + if soup is not None: + for span in soup.findAll('span', attrs={'class':'pagination'}): + span.extract() + if not first_fetch: + div = soup.find('div', attrs={'class':'headline'}) + if div: + div.extract() + return soup diff --git a/src/calibre/web/feeds/recipes/smh.py b/src/calibre/web/feeds/recipes/smh.py index 09c3347282..444b211084 100644 --- a/src/calibre/web/feeds/recipes/smh.py +++ b/src/calibre/web/feeds/recipes/smh.py @@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en' ''' smh.com.au ''' -import time +from calibre import strftime from calibre.web.feeds.news import BasicNewsRecipe from calibre.ebooks.BeautifulSoup import BeautifulSoup @@ -44,7 +44,7 @@ class SMH(BasicNewsRecipe): articles.append({ 'title': title, 'url' : url, - 'date' : time.strftime('%a, %d %b'), + 'date' : strftime('%a, %d %b'), 'description' : '', 'content' : '', }) diff --git a/src/calibre/web/feeds/recipes/wsj.py b/src/calibre/web/feeds/recipes/wsj.py index b6ab4f6f1a..ec3bc6bb93 100644 --- a/src/calibre/web/feeds/recipes/wsj.py +++ b/src/calibre/web/feeds/recipes/wsj.py @@ -4,28 +4,26 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' from calibre.web.feeds.news import BasicNewsRecipe -import re, urlparse + +# http://online.wsj.com/page/us_in_todays_paper.html class WallStreetJournal(BasicNewsRecipe): title = 'The Wall Street Journal' - __author__ = 'JTravers' + __author__ = 'Kovid Goyal' description = 'News and current affairs.' needs_subscription = True max_articles_per_feed = 10 timefmt = ' [%a, %b %d, %Y]' html2lrf_options = ['--ignore-tables'] + 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"]}, + ] + remove_tags_after = [dict(id="article_story_body"), {'class':"article story"},] - preprocess_regexps = [(re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in - [ - ## Remove anything before the body of the article. - (r'<body.*?<!-- article start', lambda match: '<body><!-- article start'), - - ## Remove anything after the end of the article. - (r'<!-- article end.*?</body>', lambda match : '</body>'), - ] - ] - + def get_browser(self): br = BasicNewsRecipe.get_browser() if self.username is not None and self.password is not None: @@ -34,11 +32,16 @@ class WallStreetJournal(BasicNewsRecipe): br['user'] = self.username br['password'] = self.password br.submit() - return br + return br + + def get_article_url(self, article): + try: + return article.feedburner_origlink.split('?')[0] + except AttributeError: + return article.link.split('?')[0] - def print_version(self, url): - article = urlparse.urlparse(url).path.rpartition('/')[-1] - return 'http://online.wsj.com/article_print/'+article + def cleanup(self): + self.browser.open('http://online.wsj.com/logout?url=http://online.wsj.com') def get_feeds(self): return [ @@ -89,7 +92,3 @@ class WallStreetJournal(BasicNewsRecipe): ('Weekend & Leisure - Sports', 'http://online.wsj.com/xml/rss/3_7204.xml'), ] -## Logout of website -## NOT CURRENTLY WORKING - # def cleanup(self): - # self.browser.open('http://commerce.wsj.com/auth/postlogout') diff --git a/src/calibre/web/feeds/templates.py b/src/calibre/web/feeds/templates.py index 37b36981ca..4438b18f0a 100644 --- a/src/calibre/web/feeds/templates.py +++ b/src/calibre/web/feeds/templates.py @@ -2,9 +2,8 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' -import datetime from calibre.utils.genshi.template import MarkupTemplate -from calibre import preferred_encoding +from calibre import preferred_encoding, strftime class Template(MarkupTemplate): @@ -126,8 +125,7 @@ class IndexTemplate(Template): def generate(self, title, datefmt, feeds): if isinstance(datefmt, unicode): datefmt = datefmt.encode(preferred_encoding) - date = datetime.datetime.now().strftime(datefmt) - date = date.decode(preferred_encoding, 'replace') + date = strftime(datefmt) return Template.generate(self, title=title, date=date, feeds=feeds) diff --git a/src/calibre/web/fetch/simple.py b/src/calibre/web/fetch/simple.py index 749c57bcde..c220e8390f 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -44,11 +44,10 @@ def save_soup(soup, target): 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, '/') - f = open(target, 'wb') html = unicode(soup) - f.write(html.encode('utf-8')) - f.close() - + with open(target, 'wb') as f: + f.write(html.encode('utf-8')) + class RecursiveFetcher(object, LoggingInterface): LINK_FILTER = tuple(re.compile(i, re.IGNORECASE) for i in @@ -59,6 +58,7 @@ class RecursiveFetcher(object, LoggingInterface): # ) # ) CSS_IMPORT_PATTERN = re.compile(r'\@import\s+url\((.*?)\)', re.IGNORECASE) + default_timeout = socket.getdefaulttimeout() # Needed here as it is used in __del__ def __init__(self, options, logger, image_map={}, css_map={}, job_info=None): LoggingInterface.__init__(self, logger) @@ -99,7 +99,7 @@ class RecursiveFetcher(object, LoggingInterface): def get_soup(self, src): nmassage = copy.copy(BeautifulSoup.MARKUP_MASSAGE) nmassage.extend(self.preprocess_regexps) - soup = BeautifulSoup(xml_to_unicode(src, self.verbose)[0], markupMassage=nmassage) + soup = BeautifulSoup(xml_to_unicode(src, self.verbose, strip_encoding_pats=True)[0], markupMassage=nmassage) if self.keep_only_tags: body = Tag(soup, 'body') @@ -118,8 +118,10 @@ class RecursiveFetcher(object, LoggingInterface): tag = tag.parent if self.remove_tags_after is not None: - tag = soup.find(**self.remove_tags_after) - remove_beyond(tag, 'nextSibling') + rt = [self.remove_tags_after] if isinstance(self.remove_tags_after, dict) else self.remove_tags_after + for spec in rt: + tag = soup.find(**spec) + remove_beyond(tag, 'nextSibling') if self.remove_tags_before is not None: tag = soup.find(**self.remove_tags_before) @@ -145,6 +147,8 @@ class RecursiveFetcher(object, LoggingInterface): if getattr(err, 'reason', [0])[0] == 104: # Connection reset by peer self.log_debug('Connection reset by peer retrying in 1 second.') time.sleep(1) + if hasattr(f, 'close'): + f.close() f = self.browser.open(url) else: raise err @@ -194,13 +198,15 @@ class RecursiveFetcher(object, LoggingInterface): try: f = self.fetch_url(iurl) except Exception, err: - self.log_warning('Could not fetch stylesheet %s', iurl) + self.log_debug('Could not fetch stylesheet %s', iurl) self.log_debug('Error: %s', str(err), exc_info=True) continue stylepath = os.path.join(diskpath, 'style'+str(c)+'.css') with self.stylemap_lock: self.stylemap[iurl] = stylepath - open(stylepath, 'wb').write(f.read()) + with open(stylepath, 'wb') as x: + x.write(f.read()) + f.close() tag['href'] = stylepath else: for ns in tag.findAll(text=True): @@ -219,12 +225,15 @@ class RecursiveFetcher(object, LoggingInterface): except Exception, err: self.log_warning('Could not fetch stylesheet %s', iurl) self.log_debug('Error: %s', str(err), exc_info=True) + if hasattr(f, 'close'): f.close() continue c += 1 stylepath = os.path.join(diskpath, 'style'+str(c)+'.css') with self.stylemap_lock: self.stylemap[iurl] = stylepath - open(stylepath, 'wb').write(f.read()) + with open(stylepath, 'wb') as x: + x.write(f.read()) + f.close() ns.replaceWith(src.replace(m.group(1), stylepath)) @@ -258,7 +267,9 @@ class RecursiveFetcher(object, LoggingInterface): imgpath = os.path.join(diskpath, fname) with self.imagemap_lock: self.imagemap[iurl] = imgpath - open(imgpath, 'wb').write(f.read()) + with open(imgpath, 'wb') as x: + x.write(f.read()) + f.close() tag['src'] = imgpath def absurl(self, baseurl, tag, key, filter=True): @@ -327,6 +338,7 @@ class RecursiveFetcher(object, LoggingInterface): self.current_dir = linkdiskpath f = self.fetch_url(iurl) dsrc = f.read() + f.close() if len(dsrc) == 0 or \ len(re.compile('<!--.*?-->', re.DOTALL).sub('', dsrc).strip()) == 0: raise ValueError('No content at URL %s'%iurl) @@ -378,7 +390,9 @@ class RecursiveFetcher(object, LoggingInterface): return res def __del__(self): - socket.setdefaulttimeout(self.default_timeout) + dt = getattr(self, 'default_timeout', None) + if dt is not None: + socket.setdefaulttimeout(dt) def option_parser(usage=_('%prog URL\n\nWhere URL is for example http://google.com')): parser = OptionParser(usage=usage) diff --git a/src/cssutils/__init__.py b/src/cssutils/__init__.py new file mode 100644 index 0000000000..901d6acf75 --- /dev/null +++ b/src/cssutils/__init__.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +"""cssutils - CSS Cascading Style Sheets library for Python + + Copyright (C) 2004-2008 Christof Hoeke + + cssutils is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + +A Python package to parse and build CSS Cascading Style Sheets. DOM only, not any rendering facilities! + +Based upon and partly implementing the following specifications : + +`CSS 2.1 <http://www.w3.org/TR/CSS21/>`__ + General CSS rules and properties are defined here +`CSS 2.1 Errata <http://www.w3.org/Style/css2-updates/CR-CSS21-20070719-errata.html>`__ + A few errata, mainly the definition of CHARSET_SYM tokens +`CSS3 Module: Syntax <http://www.w3.org/TR/css3-syntax/>`__ + Used in parts since cssutils 0.9.4. cssutils tries to use the features from CSS 2.1 and CSS 3 with preference to CSS3 but as this is not final yet some parts are from CSS 2.1 +`MediaQueries <http://www.w3.org/TR/css3-mediaqueries/>`__ + MediaQueries are part of ``stylesheets.MediaList`` since v0.9.4, used in @import and @media rules. +`Namespaces <http://dev.w3.org/csswg/css3-namespace/>`__ + Added in v0.9.1, updated to definition in CSSOM in v0.9.4, updated in 0.9.5 for dev version +`Selectors <http://www.w3.org/TR/css3-selectors/>`__ + The selector syntax defined here (and not in CSS 2.1) should be parsable with cssutils (*should* mind though ;) ) + +`DOM Level 2 Style CSS <http://www.w3.org/TR/DOM-Level-2-Style/css.html>`__ + DOM for package css +`DOM Level 2 Style Stylesheets <http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html>`__ + DOM for package stylesheets +`CSSOM <http://dev.w3.org/csswg/cssom/>`__ + A few details (mainly the NamespaceRule DOM) is taken from here. Plan is to move implementation to the stuff defined here which is newer but still no REC so might change anytime... + + +The cssutils tokenizer is a customized implementation of `CSS3 Module: Syntax (W3C Working Draft 13 August 2003) <http://www.w3.org/TR/css3-syntax/>`__ which itself is based on the CSS 2.1 tokenizer. It tries to be as compliant as possible but uses some (helpful) parts of the CSS 2.1 tokenizer. + +I guess cssutils is neither CSS 2.1 nor CSS 3 compliant but tries to at least be able to parse both grammars including some more real world cases (some CSS hacks are actually parsed and serialized). Both official grammars are not final nor bugfree but still feasible. cssutils aim is not to be fully compliant to any CSS specification (the specifications seem to be in a constant flow anyway) but cssutils *should* be able to read and write as many as possible CSS stylesheets "in the wild" while at the same time implement the official APIs which are well documented. Some minor extensions are provided as well. + +Please visit http://cthedot.de/cssutils/ for more details. + + +Tested with Python 2.5 on Windows Vista mainly. + + +This library may be used ``from cssutils import *`` which +import subpackages ``css`` and ``stylesheets``, CSSParser and +CSSSerializer classes only. + +Usage may be:: + + >>> from cssutils import * + >>> parser = CSSParser() + >>> sheet = parser.parseString(u'a { color: red}') + >>> print sheet.cssText + a { + color: red + } + +""" +__all__ = ['css', 'stylesheets', 'CSSParser', 'CSSSerializer'] +__docformat__ = 'restructuredtext' +__author__ = 'Christof Hoeke with contributions by Walter Doerwald' +__date__ = '$LastChangedDate:: 2008-08-11 11:11:23 -0700 #$:' + +VERSION = '0.9.5.1' + +__version__ = '%s $Id: __init__.py 1426 2008-08-11 18:11:23Z cthedot $' % VERSION + +import codec +import xml.dom + +# order of imports is important (partly circular) +from helper import Deprecated +import errorhandler +log = errorhandler.ErrorHandler() + +import util +import css +import stylesheets +from parse import CSSParser + +from serialize import CSSSerializer +ser = CSSSerializer() + +# used by Selector defining namespace prefix '*' +_ANYNS = -1 + +class DOMImplementationCSS(object): + """ + This interface allows the DOM user to create a CSSStyleSheet + outside the context of a document. There is no way to associate + the new CSSStyleSheet with a document in DOM Level 2. + + This class is its *own factory*, as it is given to + xml.dom.registerDOMImplementation which simply calls it and receives + an instance of this class then. + """ + _features = [ + ('css', '1.0'), + ('css', '2.0'), + ('stylesheets', '1.0'), + ('stylesheets', '2.0') + ] + + def createCSSStyleSheet(self, title, media): + """ + Creates a new CSSStyleSheet. + + title of type DOMString + The advisory title. See also the Style Sheet Interfaces + section. + media of type DOMString + The comma-separated list of media associated with the new style + sheet. See also the Style Sheet Interfaces section. + + returns + CSSStyleSheet: A new CSS style sheet. + + TODO: DOMException + SYNTAX_ERR: Raised if the specified media string value has a + syntax error and is unparsable. + """ + return css.CSSStyleSheet(title=title, media=media) + + def createDocument(self, *args): + # not needed to HTML, also not for CSS? + raise NotImplementedError + + def createDocumentType(self, *args): + # not needed to HTML, also not for CSS? + raise NotImplementedError + + def hasFeature(self, feature, version): + return (feature.lower(), unicode(version)) in self._features + +xml.dom.registerDOMImplementation('cssutils', DOMImplementationCSS) + + +def parseString(*a, **k): + return CSSParser().parseString(*a, **k) +parseString.__doc__ = CSSParser.parseString.__doc__ + +def parseFile(*a, **k): + return CSSParser().parseFile(*a, **k) +parseFile.__doc__ = CSSParser.parseFile.__doc__ + +def parseUrl(*a, **k): + return CSSParser().parseUrl(*a, **k) +parseUrl.__doc__ = CSSParser.parseUrl.__doc__ + +@Deprecated('Use cssutils.parseFile() instead.') +def parse(*a, **k): + return parseFile(*a, **k) +parse.__doc__ = CSSParser.parse.__doc__ + + +# set "ser", default serializer +def setSerializer(serializer): + """ + sets the global serializer used by all class in cssutils + """ + global ser + ser = serializer + + +def getUrls(sheet): + """ + Utility function to get all ``url(urlstring)`` values in + ``CSSImportRules`` and ``CSSStyleDeclaration`` objects (properties) + of given CSSStyleSheet ``sheet``. + + This function is a generator. The url values exclude ``url(`` and ``)`` + and surrounding single or double quotes. + """ + for importrule in (r for r in sheet if r.type == r.IMPORT_RULE): + yield importrule.href + + def getUrl(v): + if v.CSS_PRIMITIVE_VALUE == v.cssValueType and\ + v.CSS_URI == v.primitiveType: + return v.getStringValue() + + def styleDeclarations(base): + "recursive generator to find all CSSStyleDeclarations" + if hasattr(base, 'cssRules'): + for rule in base.cssRules: + for s in styleDeclarations(rule): + yield s + elif hasattr(base, 'style'): + yield base.style + + for style in styleDeclarations(sheet): + for p in style.getProperties(all=True): + v = p.cssValue + if v.CSS_VALUE_LIST == v.cssValueType: + for item in v: + u = getUrl(item) + if u is not None: + yield u + elif v.CSS_PRIMITIVE_VALUE == v.cssValueType: + u = getUrl(v) + if u is not None: + yield u + +def replaceUrls(sheet, replacer): + """ + Utility function to replace all ``url(urlstring)`` values in + ``CSSImportRules`` and ``CSSStyleDeclaration`` objects (properties) + of given CSSStyleSheet ``sheet``. + + ``replacer`` must be a function which is called with a single + argument ``urlstring`` which is the current value of url() + excluding ``url(`` and ``)`` and surrounding single or double quotes. + """ + for importrule in (r for r in sheet if r.type == r.IMPORT_RULE): + importrule.href = replacer(importrule.href) + + def setProperty(v): + if v.CSS_PRIMITIVE_VALUE == v.cssValueType and\ + v.CSS_URI == v.primitiveType: + v.setStringValue(v.CSS_URI, + replacer(v.getStringValue())) + + def styleDeclarations(base): + "recursive generator to find all CSSStyleDeclarations" + if hasattr(base, 'cssRules'): + for rule in base.cssRules: + for s in styleDeclarations(rule): + yield s + elif hasattr(base, 'style'): + yield base.style + + for style in styleDeclarations(sheet): + for p in style.getProperties(all=True): + v = p.cssValue + if v.CSS_VALUE_LIST == v.cssValueType: + for item in v: + setProperty(item) + elif v.CSS_PRIMITIVE_VALUE == v.cssValueType: + setProperty(v) + + +if __name__ == '__main__': + print __doc__ diff --git a/src/cssutils/codec.py b/src/cssutils/codec.py new file mode 100644 index 0000000000..72fbbaddec --- /dev/null +++ b/src/cssutils/codec.py @@ -0,0 +1,581 @@ +#!/usr/bin/env python +"""Python codec for CSS.""" +__docformat__ = 'restructuredtext' +__author__ = 'Walter Doerwald' +__version__ = '$Id: util.py 1114 2008-03-05 13:22:59Z cthedot $' + +import codecs, marshal + +# We're using bits to store all possible candidate encodings (or variants, i.e. +# we have two bits for the variants of UTF-16 and two for the +# variants of UTF-32). +# +# Prefixes for various CSS encodings +# UTF-8-SIG xEF xBB xBF +# UTF-16 (LE) xFF xFE ~x00|~x00 +# UTF-16 (BE) xFE xFF +# UTF-16-LE @ x00 @ x00 +# UTF-16-BE x00 @ +# UTF-32 (LE) xFF xFE x00 x00 +# UTF-32 (BE) x00 x00 xFE xFF +# UTF-32-LE @ x00 x00 x00 +# UTF-32-BE x00 x00 x00 @ +# CHARSET @ c h a ... + + +def detectencoding_str(input, final=False): + """ + Detect the encoding of the byte string ``input``, which contains the + beginning of a CSS file. This function returs the detected encoding (or + ``None`` if it hasn't got enough data), and a flag that indicates whether + to encoding has been detected explicitely or implicitely. To detect the + encoding the first few bytes are used (or if ``input`` is ASCII compatible + and starts with a charset rule the encoding name from the rule). "Explicit" + detection means that the bytes start with a BOM or a charset rule. + + If the encoding can't be detected yet, ``None`` is returned as the encoding. + ``final`` specifies whether more data is available in later calls or not. + If ``final`` is true, ``detectencoding_str()`` will never return ``None`` + as the encoding. + """ + + # A bit for every candidate + CANDIDATE_UTF_8_SIG = 1 + CANDIDATE_UTF_16_AS_LE = 2 + CANDIDATE_UTF_16_AS_BE = 4 + CANDIDATE_UTF_16_LE = 8 + CANDIDATE_UTF_16_BE = 16 + CANDIDATE_UTF_32_AS_LE = 32 + CANDIDATE_UTF_32_AS_BE = 64 + CANDIDATE_UTF_32_LE = 128 + CANDIDATE_UTF_32_BE = 256 + CANDIDATE_CHARSET = 512 + + candidates = 1023 # all candidates + + li = len(input) + if li>=1: + # Check first byte + c = input[0] + if c != "\xef": + candidates &= ~CANDIDATE_UTF_8_SIG + if c != "\xff": + candidates &= ~(CANDIDATE_UTF_32_AS_LE|CANDIDATE_UTF_16_AS_LE) + if c != "\xfe": + candidates &= ~CANDIDATE_UTF_16_AS_BE + if c != "@": + candidates &= ~(CANDIDATE_UTF_32_LE|CANDIDATE_UTF_16_LE|CANDIDATE_CHARSET) + if c != "\x00": + candidates &= ~(CANDIDATE_UTF_32_AS_BE|CANDIDATE_UTF_32_BE|CANDIDATE_UTF_16_BE) + if li>=2: + # Check second byte + c = input[1] + if c != "\xbb": + candidates &= ~CANDIDATE_UTF_8_SIG + if c != "\xfe": + candidates &= ~(CANDIDATE_UTF_16_AS_LE|CANDIDATE_UTF_32_AS_LE) + if c != "\xff": + candidates &= ~CANDIDATE_UTF_16_AS_BE + if c != "\x00": + candidates &= ~(CANDIDATE_UTF_16_LE|CANDIDATE_UTF_32_AS_BE|CANDIDATE_UTF_32_LE|CANDIDATE_UTF_32_BE) + if c != "@": + candidates &= ~CANDIDATE_UTF_16_BE + if c != "c": + candidates &= ~CANDIDATE_CHARSET + if li>=3: + # Check third byte + c = input[2] + if c != "\xbf": + candidates &= ~CANDIDATE_UTF_8_SIG + if c != "c": + candidates &= ~CANDIDATE_UTF_16_LE + if c != "\x00": + candidates &= ~(CANDIDATE_UTF_32_AS_LE|CANDIDATE_UTF_32_LE|CANDIDATE_UTF_32_BE) + if c != "\xfe": + candidates &= ~CANDIDATE_UTF_32_AS_BE + if c != "h": + candidates &= ~CANDIDATE_CHARSET + if li>=4: + # Check fourth byte + c = input[3] + if input[2:4] == "\x00\x00": + candidates &= ~CANDIDATE_UTF_16_AS_LE + if c != "\x00": + candidates &= ~(CANDIDATE_UTF_16_LE|CANDIDATE_UTF_32_AS_LE|CANDIDATE_UTF_32_LE) + if c != "\xff": + candidates &= ~CANDIDATE_UTF_32_AS_BE + if c != "@": + candidates &= ~CANDIDATE_UTF_32_BE + if c != "a": + candidates &= ~CANDIDATE_CHARSET + if candidates == 0: + return ("utf-8", False) + if not (candidates & (candidates-1)): # only one candidate remaining + if candidates == CANDIDATE_UTF_8_SIG and li >= 3: + return ("utf-8-sig", True) + elif candidates == CANDIDATE_UTF_16_AS_LE and li >= 2: + return ("utf-16", True) + elif candidates == CANDIDATE_UTF_16_AS_BE and li >= 2: + return ("utf-16", True) + elif candidates == CANDIDATE_UTF_16_LE and li >= 4: + return ("utf-16-le", False) + elif candidates == CANDIDATE_UTF_16_BE and li >= 2: + return ("utf-16-be", False) + elif candidates == CANDIDATE_UTF_32_AS_LE and li >= 4: + return ("utf-32", True) + elif candidates == CANDIDATE_UTF_32_AS_BE and li >= 4: + return ("utf-32", True) + elif candidates == CANDIDATE_UTF_32_LE and li >= 4: + return ("utf-32-le", False) + elif candidates == CANDIDATE_UTF_32_BE and li >= 4: + return ("utf-32-be", False) + elif candidates == CANDIDATE_CHARSET and li >= 4: + prefix = '@charset "' + if input[:len(prefix)] == prefix: + pos = input.find('"', len(prefix)) + if pos >= 0: + return (input[len(prefix):pos], True) + # if this is the last call, and we haven't determined an encoding yet, + # we default to UTF-8 + if final: + return ("utf-8", False) + return (None, False) # dont' know yet + + +def detectencoding_unicode(input, final=False): + """ + Detect the encoding of the unicode string ``input``, which contains the + beginning of a CSS file. The encoding is detected from the charset rule + at the beginning of ``input``. If there is no charset rule, ``"utf-8"`` + will be returned. + + If the encoding can't be detected yet, ``None`` is returned. ``final`` + specifies whether more data will be available in later calls or not. If + ``final`` is true, ``detectencoding_unicode()`` will never return ``None``. + """ + prefix = u'@charset "' + if input.startswith(prefix): + pos = input.find(u'"', len(prefix)) + if pos >= 0: + return (input[len(prefix):pos], True) + elif final or not prefix.startswith(input): + # if this is the last call, and we haven't determined an encoding yet, + # (or the string definitely doesn't start with prefix) we default to UTF-8 + return ("utf-8", False) + return (None, False) # don't know yet + + +def _fixencoding(input, encoding, final=False): + """ + Replace the name of the encoding in the charset rule at the beginning of + ``input`` with ``encoding``. If ``input`` doesn't starts with a charset + rule, ``input`` will be returned unmodified. + + If the encoding can't be found yet, ``None`` is returned. ``final`` + specifies whether more data will be available in later calls or not. + If ``final`` is true, ``_fixencoding()`` will never return ``None``. + """ + prefix = u'@charset "' + if len(input) > len(prefix): + if input.startswith(prefix): + pos = input.find(u'"', len(prefix)) + if pos >= 0: + if encoding.replace("_", "-").lower() == "utf-8-sig": + encoding = u"utf-8" + return prefix + encoding + input[pos:] + # we haven't seen the end of the encoding name yet => fall through + else: + return input # doesn't start with prefix, so nothing to fix + elif not prefix.startswith(input) or final: + # can't turn out to be a @charset rule later (or there is no "later") + return input + if final: + return input + return None # don't know yet + + +def decode(input, errors="strict", encoding=None, force=True): + if encoding is None or not force: + (_encoding, explicit) = detectencoding_str(input, True) + if _encoding == "css": + raise ValueError("css not allowed as encoding name") + if (explicit and not force) or encoding is None: # Take the encoding from the input + encoding = _encoding + (input, consumed) = codecs.getdecoder(encoding)(input, errors) + return (_fixencoding(input, unicode(encoding), True), consumed) + + +def encode(input, errors="strict", encoding=None): + consumed = len(input) + if encoding is None: + encoding = detectencoding_unicode(input, True)[0] + if encoding.replace("_", "-").lower() == "utf-8-sig": + input = _fixencoding(input, u"utf-8", True) + else: + input = _fixencoding(input, unicode(encoding), True) + if encoding == "css": + raise ValueError("css not allowed as encoding name") + encoder = codecs.getencoder(encoding) + return (encoder(input, errors)[0], consumed) + + +def _bytes2int(bytes): + # Helper: convert an 8 bit string into an ``int``. + i = 0 + for byte in bytes: + i = (i<<8) + ord(byte) + return i + + +def _int2bytes(i): + # Helper: convert an ``int`` into an 8-bit string. + v = [] + while i: + v.insert(0, chr(i&0xff)) + i >>= 8 + return "".join(v) + + +if hasattr(codecs, "IncrementalDecoder"): + class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors="strict", encoding=None, force=True): + self.decoder = None + self.encoding = encoding + self.force = force + codecs.IncrementalDecoder.__init__(self, errors) + # Store ``errors`` somewhere else, + # because we have to hide it in a property + self._errors = errors + self.buffer = "" + self.headerfixed = False + + def iterdecode(self, input): + for part in input: + result = self.decode(part, False) + if result: + yield result + result = self.decode("", True) + if result: + yield result + + def decode(self, input, final=False): + # We're doing basically the same as a ``BufferedIncrementalDecoder``, + # but since the buffer is only relevant until the encoding has been + # detected (in which case the buffer of the underlying codec might + # kick in), we're implementing buffering ourselves to avoid some + # overhead. + if self.decoder is None: + input = self.buffer + input + # Do we have to detect the encoding from the input? + if self.encoding is None or not self.force: + (encoding, explicit) = detectencoding_str(input, final) + if encoding is None: # no encoding determined yet + self.buffer = input # retry the complete input on the next call + return u"" # no encoding determined yet, so no output + elif encoding == "css": + raise ValueError("css not allowed as encoding name") + if (explicit and not self.force) or self.encoding is None: # Take the encoding from the input + self.encoding = encoding + self.buffer = "" # drop buffer, as the decoder might keep its own + decoder = codecs.getincrementaldecoder(self.encoding) + self.decoder = decoder(self._errors) + if self.headerfixed: + return self.decoder.decode(input, final) + # If we haven't fixed the header yet, + # the content of ``self.buffer`` is a ``unicode`` object + output = self.buffer + self.decoder.decode(input, final) + encoding = self.encoding + if encoding.replace("_", "-").lower() == "utf-8-sig": + encoding = "utf-8" + newoutput = _fixencoding(output, unicode(encoding), final) + if newoutput is None: + # retry fixing the @charset rule (but keep the decoded stuff) + self.buffer = output + return u"" + self.headerfixed = True + return newoutput + + def reset(self): + codecs.IncrementalDecoder.reset(self) + self.decoder = None + self.buffer = "" + self.headerfixed = False + + def _geterrors(self): + return self._errors + + def _seterrors(self, errors): + # Setting ``errors`` must be done on the real decoder too + if self.decoder is not None: + self.decoder.errors = errors + self._errors = errors + errors = property(_geterrors, _seterrors) + + def getstate(self): + if self.decoder is not None: + state = (self.encoding, self.buffer, self.headerfixed, True, self.decoder.getstate()) + else: + state = (self.encoding, self.buffer, self.headerfixed, False, None) + return ("", _bytes2int(marshal.dumps(state))) + + def setstate(self, state): + state = _int2bytes(marshal.loads(state[1])) # ignore buffered input + self.encoding = state[0] + self.buffer = state[1] + self.headerfixed = state[2] + if state[3] is not None: + self.decoder = codecs.getincrementaldecoder(self.encoding)(self._errors) + self.decoder.setstate(state[4]) + else: + self.decoder = None + + +if hasattr(codecs, "IncrementalEncoder"): + class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors="strict", encoding=None): + self.encoder = None + self.encoding = encoding + codecs.IncrementalEncoder.__init__(self, errors) + # Store ``errors`` somewhere else, + # because we have to hide it in a property + self._errors = errors + self.buffer = u"" + + def iterencode(self, input): + for part in input: + result = self.encode(part, False) + if result: + yield result + result = self.encode(u"", True) + if result: + yield result + + def encode(self, input, final=False): + if self.encoder is None: + input = self.buffer + input + if self.encoding is not None: + # Replace encoding in the @charset rule with the specified one + encoding = self.encoding + if encoding.replace("_", "-").lower() == "utf-8-sig": + encoding = "utf-8" + newinput = _fixencoding(input, unicode(encoding), final) + if newinput is None: # @charset rule incomplete => Retry next time + self.buffer = input + return "" + input = newinput + else: + # Use encoding from the @charset declaration + self.encoding = detectencoding_unicode(input, final)[0] + if self.encoding is not None: + if self.encoding == "css": + raise ValueError("css not allowed as encoding name") + info = codecs.lookup(self.encoding) + encoding = self.encoding + if self.encoding.replace("_", "-").lower() == "utf-8-sig": + input = _fixencoding(input, u"utf-8", True) + self.encoder = info.incrementalencoder(self._errors) + self.buffer = u"" + else: + self.buffer = input + return "" + return self.encoder.encode(input, final) + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.encoder = None + self.buffer = u"" + + def _geterrors(self): + return self._errors + + def _seterrors(self, errors): + # Setting ``errors ``must be done on the real encoder too + if self.encoder is not None: + self.encoder.errors = errors + self._errors = errors + errors = property(_geterrors, _seterrors) + + def getstate(self): + if self.encoder is not None: + state = (self.encoding, self.buffer, True, self.encoder.getstate()) + else: + state = (self.encoding, self.buffer, False, None) + return _bytes2int(marshal.dumps(state)) + + def setstate(self, state): + state = _int2bytes(marshal.loads(state)) + self.encoding = state[0] + self.buffer = state[1] + if state[2] is not None: + self.encoder = codecs.getincrementalencoder(self.encoding)(self._errors) + self.encoder.setstate(state[4]) + else: + self.encoder = None + + +class StreamWriter(codecs.StreamWriter): + def __init__(self, stream, errors="strict", encoding=None, header=False): + codecs.StreamWriter.__init__(self, stream, errors) + self.streamwriter = None + self.encoding = encoding + self._errors = errors + self.buffer = u"" + + def encode(self, input, errors='strict'): + li = len(input) + if self.streamwriter is None: + input = self.buffer + input + li = len(input) + if self.encoding is not None: + # Replace encoding in the @charset rule with the specified one + encoding = self.encoding + if encoding.replace("_", "-").lower() == "utf-8-sig": + encoding = "utf-8" + newinput = _fixencoding(input, unicode(encoding), False) + if newinput is None: # @charset rule incomplete => Retry next time + self.buffer = input + return ("", 0) + input = newinput + else: + # Use encoding from the @charset declaration + self.encoding = detectencoding_unicode(input, False)[0] + if self.encoding is not None: + if self.encoding == "css": + raise ValueError("css not allowed as encoding name") + self.streamwriter = codecs.getwriter(self.encoding)(self.stream, self._errors) + encoding = self.encoding + if self.encoding.replace("_", "-").lower() == "utf-8-sig": + input = _fixencoding(input, u"utf-8", True) + self.buffer = u"" + else: + self.buffer = input + return ("", 0) + return (self.streamwriter.encode(input, errors)[0], li) + + def _geterrors(self): + return self._errors + + def _seterrors(self, errors): + # Setting ``errors`` must be done on the streamwriter too + if self.streamwriter is not None: + self.streamwriter.errors = errors + self._errors = errors + errors = property(_geterrors, _seterrors) + + +class StreamReader(codecs.StreamReader): + def __init__(self, stream, errors="strict", encoding=None, force=True): + codecs.StreamReader.__init__(self, stream, errors) + self.streamreader = None + self.encoding = encoding + self.force = force + self._errors = errors + + def decode(self, input, errors='strict'): + if self.streamreader is None: + if self.encoding is None or not self.force: + (encoding, explicit) = detectencoding_str(input, False) + if encoding is None: # no encoding determined yet + return (u"", 0) # no encoding determined yet, so no output + elif encoding == "css": + raise ValueError("css not allowed as encoding name") + if (explicit and not self.force) or self.encoding is None: # Take the encoding from the input + self.encoding = encoding + streamreader = codecs.getreader(self.encoding) + streamreader = streamreader(self.stream, self._errors) + (output, consumed) = streamreader.decode(input, errors) + encoding = self.encoding + if encoding.replace("_", "-").lower() == "utf-8-sig": + encoding = "utf-8" + newoutput = _fixencoding(output, unicode(encoding), False) + if newoutput is not None: + self.streamreader = streamreader + return (newoutput, consumed) + return (u"", 0) # we will create a new streamreader on the next call + return self.streamreader.decode(input, errors) + + def _geterrors(self): + return self._errors + + def _seterrors(self, errors): + # Setting ``errors`` must be done on the streamreader too + if self.streamreader is not None: + self.streamreader.errors = errors + self._errors = errors + errors = property(_geterrors, _seterrors) + + +if hasattr(codecs, "CodecInfo"): + # We're running on Python 2.5 or better + def search_function(name): + if name == "css": + return codecs.CodecInfo( + name="css", + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) +else: + # If we're running on Python 2.4, define the utf-8-sig codec here + def utf8sig_encode(input, errors='strict'): + return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input)) + + def utf8sig_decode(input, errors='strict'): + prefix = 0 + if input[:3] == codecs.BOM_UTF8: + input = input[3:] + prefix = 3 + (output, consumed) = codecs.utf_8_decode(input, errors, True) + return (output, consumed+prefix) + + class UTF8SigStreamWriter(codecs.StreamWriter): + def reset(self): + codecs.StreamWriter.reset(self) + try: + del self.encode + except AttributeError: + pass + + def encode(self, input, errors='strict'): + self.encode = codecs.utf_8_encode + return utf8sig_encode(input, errors) + + class UTF8SigStreamReader(codecs.StreamReader): + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + if len(input) < 3 and codecs.BOM_UTF8.startswith(input): + # not enough data to decide if this is a BOM + # => try again on the next call + return (u"", 0) + self.decode = codecs.utf_8_decode + return utf8sig_decode(input, errors) + + def search_function(name): + import encodings + name = encodings.normalize_encoding(name) + if name == "css": + return (encode, decode, StreamReader, StreamWriter) + elif name == "utf_8_sig": + return (utf8sig_encode, utf8sig_decode, UTF8SigStreamReader, UTF8SigStreamWriter) + + +codecs.register(search_function) + + +# Error handler for CSS escaping + +def cssescape(exc): + if not isinstance(exc, UnicodeEncodeError): + raise TypeError("don't know how to handle %r" % exc) + return (u"".join(u"\\%06x" % ord(c) for c in exc.object[exc.start:exc.end]), exc.end) + +codecs.register_error("cssescape", cssescape) diff --git a/src/cssutils/css/__init__.py b/src/cssutils/css/__init__.py new file mode 100644 index 0000000000..b4ee3b8d9c --- /dev/null +++ b/src/cssutils/css/__init__.py @@ -0,0 +1,63 @@ +""" +Document Object Model Level 2 CSS +http://www.w3.org/TR/2000/PR-DOM-Level-2-Style-20000927/css.html + +currently implemented + - CSSStyleSheet + - CSSRuleList + - CSSRule + - CSSComment (cssutils addon) + - CSSCharsetRule + - CSSFontFaceRule + - CSSImportRule + - CSSMediaRule + - CSSNamespaceRule (WD) + - CSSPageRule + - CSSStyleRule + - CSSUnkownRule + - Selector and SelectorList + - CSSStyleDeclaration + - CSS2Properties + - CSSValue + - CSSPrimitiveValue + - CSSValueList + +todo + - RGBColor, Rect, Counter +""" +__all__ = [ + 'CSSStyleSheet', + 'CSSRuleList', + 'CSSRule', + 'CSSComment', + 'CSSCharsetRule', + 'CSSFontFaceRule' + 'CSSImportRule', + 'CSSMediaRule', + 'CSSNamespaceRule', + 'CSSPageRule', + 'CSSStyleRule', + 'CSSUnknownRule', + 'Selector', 'SelectorList', + 'CSSStyleDeclaration', 'Property', + 'CSSValue', 'CSSPrimitiveValue', 'CSSValueList' + ] +__docformat__ = 'restructuredtext' +__version__ = '$Id: __init__.py 1116 2008-03-05 13:52:23Z cthedot $' + +from cssstylesheet import * +from cssrulelist import * +from cssrule import * +from csscomment import * +from csscharsetrule import * +from cssfontfacerule import * +from cssimportrule import * +from cssmediarule import * +from cssnamespacerule import * +from csspagerule import * +from cssstylerule import * +from cssunknownrule import * +from selector import * +from selectorlist import * +from cssstyledeclaration import * +from cssvalue import * diff --git a/src/cssutils/css/csscharsetrule.py b/src/cssutils/css/csscharsetrule.py new file mode 100644 index 0000000000..4594dd112d --- /dev/null +++ b/src/cssutils/css/csscharsetrule.py @@ -0,0 +1,165 @@ +"""CSSCharsetRule implements DOM Level 2 CSS CSSCharsetRule. + +TODO: + - check encoding syntax and not codecs.lookup? +""" +__all__ = ['CSSCharsetRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: csscharsetrule.py 1170 2008-03-20 17:42:07Z cthedot $' + +import codecs +import xml.dom +import cssrule +import cssutils + +class CSSCharsetRule(cssrule.CSSRule): + """ + The CSSCharsetRule interface represents an @charset rule in a CSS style + sheet. The value of the encoding attribute does not affect the encoding + of text data in the DOM objects; this encoding is always UTF-16 + (also in Python?). After a stylesheet is loaded, the value of the + encoding attribute is the value found in the @charset rule. If there + was no @charset in the original document, then no CSSCharsetRule is + created. The value of the encoding attribute may also be used as a hint + for the encoding used on serialization of the style sheet. + + The value of the @charset rule (and therefore of the CSSCharsetRule) + may not correspond to the encoding the document actually came in; + character encoding information e.g. in an HTTP header, has priority + (see CSS document representation) but this is not reflected in the + CSSCharsetRule. + + Properties + ========== + cssText: of type DOMString + The parsable textual representation of this rule + encoding: of type DOMString + The encoding information used in this @charset rule. + + Inherits properties from CSSRule + + Format + ====== + charsetrule: + CHARSET_SYM S* STRING S* ';' + + BUT: Only valid format is: + @charset "ENCODING"; + """ + type = property(lambda self: cssrule.CSSRule.CHARSET_RULE) + + def __init__(self, encoding=None, parentRule=None, + parentStyleSheet=None, readonly=False): + """ + encoding: + a valid character encoding + readonly: + defaults to False, not used yet + + if readonly allows setting of properties in constructor only + """ + super(CSSCharsetRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = '@charset' + self._encoding = None + if encoding: + self.encoding = encoding + + self._readonly = readonly + + def _getCssText(self): + """returns serialized property cssText""" + return cssutils.ser.do_CSSCharsetRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - HIERARCHY_REQUEST_ERR: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSCharsetRule, self)._setCssText(cssText) + + wellformed = True + tokenizer = self._tokenize2(cssText) + + if self._type(self._nexttoken(tokenizer)) != self._prods.CHARSET_SYM: + wellformed = False + self._log.error(u'CSSCharsetRule must start with "@charset "', + error=xml.dom.InvalidModificationErr) + + encodingtoken = self._nexttoken(tokenizer) + encodingtype = self._type(encodingtoken) + encoding = self._stringtokenvalue(encodingtoken) + if self._prods.STRING != encodingtype or not encoding: + wellformed = False + self._log.error(u'CSSCharsetRule: no encoding found; %r.' % + self._valuestr(cssText)) + + semicolon = self._tokenvalue(self._nexttoken(tokenizer)) + EOFtype = self._type(self._nexttoken(tokenizer)) + if u';' != semicolon or EOFtype not in ('EOF', None): + wellformed = False + self._log.error(u'CSSCharsetRule: Syntax Error: %r.' % + self._valuestr(cssText)) + + if wellformed: + self.encoding = encoding + + cssText = property(fget=_getCssText, fset=_setCssText, + doc="(DOM) The parsable textual representation.") + + def _setEncoding(self, encoding): + """ + DOMException on setting + + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if this encoding rule is readonly. + - SYNTAX_ERR: (self) + Raised if the specified encoding value has a syntax error and + is unparsable. + Currently only valid Python encodings are allowed. + """ + self._checkReadonly() + tokenizer = self._tokenize2(encoding) + encodingtoken = self._nexttoken(tokenizer) + unexpected = self._nexttoken(tokenizer) + + valid = True + if not encodingtoken or unexpected or\ + self._prods.IDENT != self._type(encodingtoken): + valid = False + self._log.error( + 'CSSCharsetRule: Syntax Error in encoding value %r.' % + encoding) + else: + try: + codecs.lookup(encoding) + except LookupError: + valid = False + self._log.error('CSSCharsetRule: Unknown (Python) encoding %r.' % + encoding) + else: + self._encoding = encoding.lower() + + encoding = property(lambda self: self._encoding, _setEncoding, + doc="(DOM)The encoding information used in this @charset rule.") + + wellformed = property(lambda self: bool(self.encoding)) + + def __repr__(self): + return "cssutils.css.%s(encoding=%r)" % ( + self.__class__.__name__, self.encoding) + + def __str__(self): + return "<cssutils.css.%s object encoding=%r at 0x%x>" % ( + self.__class__.__name__, self.encoding, id(self)) diff --git a/src/cssutils/css/csscomment.py b/src/cssutils/css/csscomment.py new file mode 100644 index 0000000000..e69c2c77cc --- /dev/null +++ b/src/cssutils/css/csscomment.py @@ -0,0 +1,92 @@ +"""CSSComment is not defined in DOM Level 2 at all but a cssutils defined +class only. +Implements CSSRule which is also extended for a CSSComment rule type +""" +__all__ = ['CSSComment'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: csscomment.py 1170 2008-03-20 17:42:07Z cthedot $' + +import xml.dom +import cssrule +import cssutils + +class CSSComment(cssrule.CSSRule): + """ + (cssutils) a CSS comment + + Properties + ========== + cssText: of type DOMString + The comment text including comment delimiters + + Inherits properties from CSSRule + + Format + ====== + :: + + /*...*/ + """ + type = property(lambda self: cssrule.CSSRule.COMMENT) # value = -1 + # constant but needed: + wellformed = True + + def __init__(self, cssText=None, parentRule=None, + parentStyleSheet=None, readonly=False): + super(CSSComment, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + + self._cssText = None + if cssText: + self._setCssText(cssText) + + self._readonly = readonly + + def _getCssText(self): + """returns serialized property cssText""" + return cssutils.ser.do_CSSComment(self) + + def _setCssText(self, cssText): + """ + cssText + textual text to set or tokenlist which is not tokenized + anymore. May also be a single token for this rule + parser + if called from cssparser directly this is Parser instance + + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSComment, self)._setCssText(cssText) + tokenizer = self._tokenize2(cssText) + + commenttoken = self._nexttoken(tokenizer) + unexpected = self._nexttoken(tokenizer) + + if not commenttoken or\ + self._type(commenttoken) != self._prods.COMMENT or\ + unexpected: + self._log.error(u'CSSComment: Not a CSSComment: %r' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + self._cssText = self._tokenvalue(commenttoken) + + cssText = property(_getCssText, _setCssText, + doc=u"(cssutils) Textual representation of this comment") + + def __repr__(self): + return "cssutils.css.%s(cssText=%r)" % ( + self.__class__.__name__, self.cssText) + + def __str__(self): + return "<cssutils.css.%s object cssText=%r at 0x%x>" % ( + self.__class__.__name__, self.cssText, id(self)) diff --git a/src/cssutils/css/cssfontfacerule.py b/src/cssutils/css/cssfontfacerule.py new file mode 100644 index 0000000000..1f839c6779 --- /dev/null +++ b/src/cssutils/css/cssfontfacerule.py @@ -0,0 +1,163 @@ +"""CSSFontFaceRule implements DOM Level 2 CSS CSSFontFaceRule. +""" +__all__ = ['CSSFontFaceRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssfontfacerule.py 1284 2008-06-05 16:29:17Z cthedot $' + +import xml.dom +import cssrule +import cssutils +from cssstyledeclaration import CSSStyleDeclaration + +class CSSFontFaceRule(cssrule.CSSRule): + """ + The CSSFontFaceRule interface represents a @font-face rule in a CSS + style sheet. The @font-face rule is used to hold a set of font + descriptions. + + Properties + ========== + atkeyword (cssutils only) + the literal keyword used + cssText: of type DOMString + The parsable textual representation of this rule + style: of type CSSStyleDeclaration + The declaration-block of this rule. + + Inherits properties from CSSRule + + Format + ====== + :: + + font_face + : FONT_FACE_SYM S* + '{' S* declaration [ ';' S* declaration ]* '}' S* + ; + """ + type = property(lambda self: cssrule.CSSRule.FONT_FACE_RULE) + # constant but needed: + wellformed = True + + def __init__(self, style=None, parentRule=None, + parentStyleSheet=None, readonly=False): + """ + if readonly allows setting of properties in constructor only + + style + CSSStyleDeclaration for this CSSStyleRule + """ + super(CSSFontFaceRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = u'@font-face' + if style: + self.style = style + else: + self._style = CSSStyleDeclaration(parentRule=self) + + self._readonly = readonly + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_CSSFontFaceRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - SYNTAX_ERR: (self, StyleDeclaration) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - HIERARCHY_REQUEST_ERR: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSFontFaceRule, self)._setCssText(cssText) + + tokenizer = self._tokenize2(cssText) + attoken = self._nexttoken(tokenizer, None) + if self._type(attoken) != self._prods.FONT_FACE_SYM: + self._log.error(u'CSSFontFaceRule: No CSSFontFaceRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + wellformed = True + beforetokens, brace = self._tokensupto2(tokenizer, + blockstartonly=True, + separateEnd=True) + if self._tokenvalue(brace) != u'{': + wellformed = False + self._log.error( + u'CSSFontFaceRule: No start { of style declaration found: %r' % + self._valuestr(cssText), brace) + + # parse stuff before { which should be comments and S only + new = {'wellformed': True} + newseq = self._tempSeq()#[] + + beforewellformed, expected = self._parse(expected=':', + seq=newseq, tokenizer=self._tokenize2(beforetokens), + productions={}) + wellformed = wellformed and beforewellformed and new['wellformed'] + + styletokens, braceorEOFtoken = self._tokensupto2(tokenizer, + blockendonly=True, + separateEnd=True) + + val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken) + if val != u'}' and typ != 'EOF': + wellformed = False + self._log.error( + u'CSSFontFaceRule: No "}" after style declaration found: %r' % + self._valuestr(cssText)) + + nonetoken = self._nexttoken(tokenizer) + if nonetoken: + wellformed = False + self._log.error(u'CSSFontFaceRule: Trailing content found.', + token=nonetoken) + + newstyle = CSSStyleDeclaration() + if 'EOF' == typ: + # add again as style needs it + styletokens.append(braceorEOFtoken) + newstyle.cssText = styletokens + + if wellformed: + self.style = newstyle + self._setSeq(newseq) # contains (probably comments) upto { only + + cssText = property(_getCssText, _setCssText, + doc="(DOM) The parsable textual representation of the rule.") + + def _getStyle(self): + return self._style + + def _setStyle(self, style): + """ + style + StyleDeclaration or string + """ + self._checkReadonly() + if isinstance(style, basestring): + self._style = CSSStyleDeclaration(parentRule=self, cssText=style) + else: + self._style._seq = style.seq + + style = property(_getStyle, _setStyle, + doc="(DOM) The declaration-block of this rule set.") + + def __repr__(self): + return "cssutils.css.%s(style=%r)" % ( + self.__class__.__name__, self.style.cssText) + + def __str__(self): + return "<cssutils.css.%s object style=%r at 0x%x>" % ( + self.__class__.__name__, self.style.cssText, id(self)) diff --git a/src/cssutils/css/cssimportrule.py b/src/cssutils/css/cssimportrule.py new file mode 100644 index 0000000000..fde1b9b303 --- /dev/null +++ b/src/cssutils/css/cssimportrule.py @@ -0,0 +1,399 @@ +"""CSSImportRule implements DOM Level 2 CSS CSSImportRule. + +plus: + +``name`` property + http://www.w3.org/TR/css3-cascade/#cascading + +""" +__all__ = ['CSSImportRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssimportrule.py 1401 2008-07-29 21:07:54Z cthedot $' + +import os +import urllib +import urlparse +import xml.dom +import cssrule +import cssutils + +class CSSImportRule(cssrule.CSSRule): + """ + Represents an @import rule within a CSS style sheet. The @import rule + is used to import style rules from other style sheets. + + Properties + ========== + atkeyword: (cssutils only) + the literal keyword used + cssText: of type DOMString + The parsable textual representation of this rule + href: of type DOMString, (DOM readonly, cssutils also writable) + The location of the style sheet to be imported. The attribute will + not contain the url(...) specifier around the URI. + hreftype: 'uri' (serializer default) or 'string' (cssutils only) + The original type of href, not really relevant as it may be + reconfigured in the serializer but it is kept anyway + media: of type stylesheets::MediaList (DOM readonly) + A list of media types for this rule of type MediaList. + name: + An optional name used for cascading + styleSheet: of type CSSStyleSheet (DOM readonly) + The style sheet referred to by this rule. The value of this + attribute is None if the style sheet has not yet been loaded or if + it will not be loaded (e.g. if the stylesheet is for a media type + not supported by the user agent). + + Inherits properties from CSSRule + + Format + ====== + import + : IMPORT_SYM S* + [STRING|URI] S* [ medium [ COMMA S* medium]* ]? S* STRING? S* ';' S* + ; + """ + type = property(lambda self: cssrule.CSSRule.IMPORT_RULE) + + def __init__(self, href=None, mediaText=u'all', name=None, + parentRule=None, parentStyleSheet=None, readonly=False): + """ + if readonly allows setting of properties in constructor only + + Do not use as positional but as keyword attributes only! + + href + location of the style sheet to be imported. + mediaText + A list of media types for which this style sheet may be used + as a string + """ + super(CSSImportRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = u'@import' + self.hreftype = None + self._styleSheet = None + + self._href = None + self.href = href + + self._media = cssutils.stylesheets.MediaList() + if mediaText: + self._media.mediaText = mediaText + + self._name = name + + seq = self._tempSeq() + seq.append(self.href, 'href') + seq.append(self.media, 'media') + seq.append(self.name, 'name') + self._setSeq(seq) + self._readonly = readonly + + _usemedia = property(lambda self: self.media.mediaText not in (u'', u'all'), + doc="if self._media is used (or simply empty)") + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_CSSImportRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - HIERARCHY_REQUEST_ERR: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - INVALID_MODIFICATION_ERR: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + """ + super(CSSImportRule, self)._setCssText(cssText) + tokenizer = self._tokenize2(cssText) + attoken = self._nexttoken(tokenizer, None) + if self._type(attoken) != self._prods.IMPORT_SYM: + self._log.error(u'CSSImportRule: No CSSImportRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + # for closures: must be a mutable + new = {'keyword': self._tokenvalue(attoken), + 'href': None, + 'hreftype': None, + 'media': None, + 'name': None, + 'wellformed': True + } + + def __doname(seq, token): + # called by _string or _ident + new['name'] = self._stringtokenvalue(token) + seq.append(new['name'], 'name') + return ';' + + def _string(expected, seq, token, tokenizer=None): + if 'href' == expected: + # href + new['href'] = self._stringtokenvalue(token) + new['hreftype'] = 'string' + seq.append(new['href'], 'href') + return 'media name ;' + elif 'name' in expected: + # name + return __doname(seq, token) + else: + new['wellformed'] = False + self._log.error( + u'CSSImportRule: Unexpected string.', token) + return expected + + def _uri(expected, seq, token, tokenizer=None): + # href + if 'href' == expected: + uri = self._uritokenvalue(token) + new['hreftype'] = 'uri' + new['href'] = uri + seq.append(new['href'], 'href') + return 'media name ;' + else: + new['wellformed'] = False + self._log.error( + u'CSSImportRule: Unexpected URI.', token) + return expected + + def _ident(expected, seq, token, tokenizer=None): + # medialist ending with ; which is checked upon too + if expected.startswith('media'): + mediatokens = self._tokensupto2( + tokenizer, importmediaqueryendonly=True) + mediatokens.insert(0, token) # push found token + + last = mediatokens.pop() # retrieve ; + lastval, lasttyp = self._tokenvalue(last), self._type(last) + if lastval != u';' and lasttyp not in ('EOF', self._prods.STRING): + new['wellformed'] = False + self._log.error(u'CSSImportRule: No ";" found: %s' % + self._valuestr(cssText), token=token) + + media = cssutils.stylesheets.MediaList() + media.mediaText = mediatokens + if media.wellformed: + new['media'] = media + seq.append(media, 'media') + else: + new['wellformed'] = False + self._log.error(u'CSSImportRule: Invalid MediaList: %s' % + self._valuestr(cssText), token=token) + + if lasttyp == self._prods.STRING: + # name + return __doname(seq, last) + else: + return 'EOF' # ';' is token "last" + else: + new['wellformed'] = False + self._log.error( + u'CSSImportRule: Unexpected ident.', token) + return expected + + def _char(expected, seq, token, tokenizer=None): + # final ; + val = self._tokenvalue(token) + if expected.endswith(';') and u';' == val: + return 'EOF' + else: + new['wellformed'] = False + self._log.error( + u'CSSImportRule: Unexpected char.', token) + return expected + + # import : IMPORT_SYM S* [STRING|URI] + # S* [ medium [ ',' S* medium]* ]? ';' S* + # STRING? # see http://www.w3.org/TR/css3-cascade/#cascading + # ; + newseq = self._tempSeq() + wellformed, expected = self._parse(expected='href', + seq=newseq, tokenizer=tokenizer, + productions={'STRING': _string, + 'URI': _uri, + 'IDENT': _ident, + 'CHAR': _char}, + new=new) + + # wellformed set by parse + wellformed = wellformed and new['wellformed'] + + # post conditions + if not new['href']: + wellformed = False + self._log.error(u'CSSImportRule: No href found: %s' % + self._valuestr(cssText)) + + if expected != 'EOF': + wellformed = False + self._log.error(u'CSSImportRule: No ";" found: %s' % + self._valuestr(cssText)) + + # set all + if wellformed: + self.atkeyword = new['keyword'] + self.hreftype = new['hreftype'] + if new['media']: + # use same object + self.media.mediaText = new['media'].mediaText + # put it in newseq too + for index, x in enumerate(newseq): + if x.type == 'media': + newseq.replace(index, self.media, + x.type, x.line, x.col) + break + else: + # reset media + self.media.mediaText = u'all' + newseq.append(self.media, 'media') + self.name = new['name'] + self._setSeq(newseq) + self.href = new['href'] + + if self.styleSheet: + # title is set by href + #self.styleSheet._href = self.href + self.styleSheet._parentStyleSheet = self.parentStyleSheet + + cssText = property(fget=_getCssText, fset=_setCssText, + doc="(DOM attribute) The parsable textual representation.") + + def _setHref(self, href): + # update seq + for i, item in enumerate(self.seq): + val, typ = item.value, item.type + if 'href' == typ: + self._seq[i] = (href, typ, item.line, item.col) + break + else: + seq = self._tempSeq() + seq.append(self.href, 'href') + self._setSeq(seq) + # set new href + self._href = href + if not self.styleSheet: + # set only if not set before + self.__setStyleSheet() + + href = property(lambda self: self._href, _setHref, + doc="Location of the style sheet to be imported.") + + media = property(lambda self: self._media, + doc=u"(DOM readonly) A list of media types for this rule" + " of type MediaList") + + def _setName(self, name): + """raises xml.dom.SyntaxErr if name is not a string""" + if isinstance(name, basestring) or name is None: + # "" or '' + if not name: + name = None + # update seq + for i, item in enumerate(self.seq): + val, typ = item.value, item.type + if 'name' == typ: + self._seq[i] = (name, typ, item.line, item.col) + break + else: + # append + seq = self._tempSeq() + for item in self.seq: + # copy current seq + seq.append(item.value, item.type, item.line, item.col) + seq.append(name, 'name') + self._setSeq(seq) + self._name = name + # set title of referred sheet + if self.styleSheet: + self.styleSheet.title = name + else: + self._log.error(u'CSSImportRule: Not a valid name: %s' % name) + + name = property(lambda self: self._name, _setName, + doc=u"An optional name for the imported sheet") + + def __setStyleSheet(self): + """Read new CSSStyleSheet cssText from href using parentStyleSheet.href + + Indirectly called if setting ``href``. In case of any error styleSheet + is set to ``None``. + """ + # should simply fail so all errors are catched! + if self.parentStyleSheet and self.href: + # relative href + parentHref = self.parentStyleSheet.href + if parentHref is None: + # use cwd instead + parentHref = u'file:' + urllib.pathname2url(os.getcwd()) + '/' + href = urlparse.urljoin(parentHref, self.href) + + # all possible exceptions are ignored (styleSheet is None then) + try: + usedEncoding, enctype, cssText = self.parentStyleSheet._resolveImport(href) + if cssText is None: + # catched in next except below! + raise IOError('Cannot read Stylesheet.') + styleSheet = cssutils.css.CSSStyleSheet(href=href, + media=self.media, + ownerRule=self, + title=self.name) + # inherit fetcher for @imports in styleSheet + styleSheet._setFetcher(self.parentStyleSheet._fetcher) + # contentEncoding with parentStyleSheet.overrideEncoding, + # HTTP or parent + encodingOverride, encoding = None, None + if enctype == 0: + encodingOverride = usedEncoding + elif 5 > enctype > 0: + encoding = usedEncoding + + styleSheet._setCssTextWithEncodingOverride(cssText, + encodingOverride=encodingOverride, + encoding=encoding) + + except (OSError, IOError, ValueError), e: + self._log.warn(u'CSSImportRule: While processing imported style sheet href=%r: %r' + % (self.href, e), neverraise=True) + else: + self._styleSheet = styleSheet + + styleSheet = property(lambda self: self._styleSheet, + doc="(readonly) The style sheet referred to by this rule.") + + def _getWellformed(self): + "depending if media is used at all" + if self._usemedia: + return bool(self.href and self.media.wellformed) + else: + return bool(self.href) + + wellformed = property(_getWellformed) + + def __repr__(self): + if self._usemedia: + mediaText = self.media.mediaText + else: + mediaText = None + return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % ( + self.__class__.__name__, + self.href, self.media.mediaText, self.name) + + def __str__(self): + if self._usemedia: + mediaText = self.media.mediaText + else: + mediaText = None + return "<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>" % ( + self.__class__.__name__, self.href, mediaText, self.name, id(self)) diff --git a/src/cssutils/css/cssmediarule.py b/src/cssutils/css/cssmediarule.py new file mode 100644 index 0000000000..8f84f08ae4 --- /dev/null +++ b/src/cssutils/css/cssmediarule.py @@ -0,0 +1,349 @@ +"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule. +""" +__all__ = ['CSSMediaRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssmediarule.py 1370 2008-07-14 20:15:03Z cthedot $' + +import xml.dom +import cssrule +import cssutils + +class CSSMediaRule(cssrule.CSSRule): + """ + Objects implementing the CSSMediaRule interface can be identified by the + MEDIA_RULE constant. On these objects the type attribute must return the + value of that constant. + + Properties + ========== + atkeyword: (cssutils only) + the literal keyword used + cssRules: A css::CSSRuleList of all CSS rules contained within the + media block. + cssText: of type DOMString + The parsable textual representation of this rule + media: of type stylesheets::MediaList, (DOM readonly) + A list of media types for this rule of type MediaList. + name: + An optional name used for cascading + + Format + ====== + media + : MEDIA_SYM S* medium [ COMMA S* medium ]* + + STRING? # the name + + LBRACE S* ruleset* '}' S*; + """ + # CONSTANT + type = property(lambda self: cssrule.CSSRule.MEDIA_RULE) + + def __init__(self, mediaText='all', name=None, + parentRule=None, parentStyleSheet=None, readonly=False): + """constructor""" + super(CSSMediaRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = u'@media' + self._media = cssutils.stylesheets.MediaList(mediaText, + readonly=readonly) + self.name = name + self.cssRules = cssutils.css.cssrulelist.CSSRuleList() + self.cssRules.append = self.insertRule + self.cssRules.extend = self.insertRule + self.cssRules.__delitem__ == self.deleteRule + + self._readonly = readonly + + def __iter__(self): + """generator which iterates over cssRules.""" + for rule in self.cssRules: + yield rule + + def _getCssText(self): + """return serialized property cssText""" + return cssutils.ser.do_CSSMediaRule(self) + + def _setCssText(self, cssText): + """ + :param cssText: + a parseable string or a tuple of (cssText, dict-of-namespaces) + :Exceptions: + - `NAMESPACE_ERR`: (Selector) + Raised if a specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (self, StyleDeclaration, etc) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - `INVALID_MODIFICATION_ERR`: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSMediaRule, self)._setCssText(cssText) + + # might be (cssText, namespaces) + cssText, namespaces = self._splitNamespacesOff(cssText) + try: + # use parent style sheet ones if available + namespaces = self.parentStyleSheet.namespaces + except AttributeError: + pass + + tokenizer = self._tokenize2(cssText) + attoken = self._nexttoken(tokenizer, None) + if self._type(attoken) != self._prods.MEDIA_SYM: + self._log.error(u'CSSMediaRule: No CSSMediaRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + # media "name"? { cssRules } + + # media + wellformed = True + mediatokens, end = self._tokensupto2(tokenizer, + mediaqueryendonly=True, + separateEnd=True) + if u'{' == self._tokenvalue(end) or self._prods.STRING == self._type(end): + newmedia = cssutils.stylesheets.MediaList() + newmedia.mediaText = mediatokens + + # name (optional) + name = None + nameseq = self._tempSeq() + if self._prods.STRING == self._type(end): + name = self._stringtokenvalue(end) + # TODO: for now comments are lost after name + nametokens, end = self._tokensupto2(tokenizer, + blockstartonly=True, + separateEnd=True) + wellformed, expected = self._parse(None, nameseq, nametokens, {}) + if not wellformed: + self._log.error(u'CSSMediaRule: Syntax Error: %s' % + self._valuestr(cssText)) + + + # check for { + if u'{' != self._tokenvalue(end): + self._log.error(u'CSSMediaRule: No "{" found: %s' % + self._valuestr(cssText)) + return + + # cssRules + cssrulestokens, braceOrEOF = self._tokensupto2(tokenizer, + mediaendonly=True, + separateEnd=True) + nonetoken = self._nexttoken(tokenizer, None) + if (u'}' != self._tokenvalue(braceOrEOF) and + 'EOF' != self._type(braceOrEOF)): + self._log.error(u'CSSMediaRule: No "}" found.', + token=braceOrEOF) + elif nonetoken: + self._log.error(u'CSSMediaRule: Trailing content found.', + token=nonetoken) + else: + # for closures: must be a mutable + newcssrules = [] #cssutils.css.CSSRuleList() + new = {'wellformed': True } + + def ruleset(expected, seq, token, tokenizer): + rule = cssutils.css.CSSStyleRule(parentRule=self) + rule.cssText = (self._tokensupto2(tokenizer, token), + namespaces) + if rule.wellformed: + rule._parentStyleSheet=self.parentStyleSheet + seq.append(rule) + return expected + + def atrule(expected, seq, token, tokenizer): + # TODO: get complete rule! + tokens = self._tokensupto2(tokenizer, token) + atval = self._tokenvalue(token) + if atval in ('@charset ', '@font-face', '@import', '@namespace', + '@page', '@media'): + self._log.error( + u'CSSMediaRule: This rule is not allowed in CSSMediaRule - ignored: %s.' + % self._valuestr(tokens), + token = token, + error=xml.dom.HierarchyRequestErr) + else: + rule = cssutils.css.CSSUnknownRule(parentRule=self, + parentStyleSheet=self.parentStyleSheet) + rule.cssText = tokens + if rule.wellformed: + seq.append(rule) + return expected + + def COMMENT(expected, seq, token, tokenizer=None): + seq.append(cssutils.css.CSSComment([token])) + return expected + + tokenizer = (t for t in cssrulestokens) # TODO: not elegant! + wellformed, expected = self._parse(braceOrEOF, + newcssrules, + tokenizer, { + 'COMMENT': COMMENT, + 'CHARSET_SYM': atrule, + 'FONT_FACE_SYM': atrule, + 'IMPORT_SYM': atrule, + 'NAMESPACE_SYM': atrule, + 'PAGE_SYM': atrule, + 'MEDIA_SYM': atrule, + 'ATKEYWORD': atrule + }, + default=ruleset, + new=new) + + # no post condition + if newmedia.wellformed and wellformed: + # keep reference + self._media.mediaText = newmedia.mediaText + self.name = name + self._setSeq(nameseq) + del self.cssRules[:] + for r in newcssrules: + self.cssRules.append(r) + + cssText = property(_getCssText, _setCssText, + doc="(DOM attribute) The parsable textual representation.") + + def _setName(self, name): + if isinstance(name, basestring) or name is None: + # "" or '' + if not name: + name = None + + self._name = name + else: + self._log.error(u'CSSImportRule: Not a valid name: %s' % name) + + + name = property(lambda self: self._name, _setName, + doc=u"An optional name for the media rules") + + media = property(lambda self: self._media, + doc=u"(DOM readonly) A list of media types for this rule of type\ + MediaList") + + wellformed = property(lambda self: self.media.wellformed) + + def deleteRule(self, index): + """ + index + within the media block's rule collection of the rule to remove. + + Used to delete a rule from the media block. + + DOMExceptions + + - INDEX_SIZE_ERR: (self) + Raised if the specified index does not correspond to a rule in + the media rule list. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this media rule is readonly. + """ + self._checkReadonly() + + try: + self.cssRules[index]._parentRule = None # detach + del self.cssRules[index] # remove from @media + except IndexError: + raise xml.dom.IndexSizeErr( + u'CSSMediaRule: %s is not a valid index in the rulelist of length %i' % ( + index, self.cssRules.length)) + + def add(self, rule): + """Add rule to end of this mediarule. Same as ``.insertRule(rule)``.""" + self.insertRule(rule, index=None) + + def insertRule(self, rule, index=None): + """ + rule + The parsable text representing the rule. For rule sets this + contains both the selector and the style declaration. For + at-rules, this specifies both the at-identifier and the rule + content. + + cssutils also allows rule to be a valid **CSSRule** object + + index + within the media block's rule collection of the rule before + which to insert the specified rule. If the specified index is + equal to the length of the media blocks's rule collection, the + rule will be added to the end of the media block. + If index is not given or None rule will be appended to rule + list. + + Used to insert a new rule into the media block. + + DOMException on setting + + - HIERARCHY_REQUEST_ERR: + (no use case yet as no @charset or @import allowed)) + Raised if the rule cannot be inserted at the specified index, + e.g., if an @import rule is inserted after a standard rule set + or other at-rule. + - INDEX_SIZE_ERR: (self) + Raised if the specified index is not a valid insertion point. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this media rule is readonly. + - SYNTAX_ERR: (CSSStyleRule) + Raised if the specified rule has a syntax error and is + unparsable. + + returns the index within the media block's rule collection of the + newly inserted rule. + + """ + self._checkReadonly() + + # check position + if index is None: + index = len(self.cssRules) + elif index < 0 or index > self.cssRules.length: + raise xml.dom.IndexSizeErr( + u'CSSMediaRule: Invalid index %s for CSSRuleList with a length of %s.' % ( + index, self.cssRules.length)) + + # parse + if isinstance(rule, basestring): + tempsheet = cssutils.css.CSSStyleSheet() + tempsheet.cssText = rule + if len(tempsheet.cssRules) != 1 or (tempsheet.cssRules and + not isinstance(tempsheet.cssRules[0], cssutils.css.CSSRule)): + self._log.error(u'CSSMediaRule: Invalid Rule: %s' % rule) + return + rule = tempsheet.cssRules[0] + elif not isinstance(rule, cssutils.css.CSSRule): + self._log.error(u'CSSMediaRule: Not a CSSRule: %s' % rule) + return + + # CHECK HIERARCHY + # @charset @import @page @namespace @media + if isinstance(rule, cssutils.css.CSSCharsetRule) or \ + isinstance(rule, cssutils.css.CSSFontFaceRule) or \ + isinstance(rule, cssutils.css.CSSImportRule) or \ + isinstance(rule, cssutils.css.CSSNamespaceRule) or \ + isinstance(rule, cssutils.css.CSSPageRule) or \ + isinstance(rule, CSSMediaRule): + self._log.error(u'CSSMediaRule: This type of rule is not allowed here: %s' % + rule.cssText, + error=xml.dom.HierarchyRequestErr) + return + + self.cssRules.insert(index, rule) + rule._parentRule = self + rule._parentStyleSheet = self.parentStyleSheet + return index + + def __repr__(self): + return "cssutils.css.%s(mediaText=%r)" % ( + self.__class__.__name__, self.media.mediaText) + + def __str__(self): + return "<cssutils.css.%s object mediaText=%r at 0x%x>" % ( + self.__class__.__name__, self.media.mediaText, id(self)) diff --git a/src/cssutils/css/cssnamespacerule.py b/src/cssutils/css/cssnamespacerule.py new file mode 100644 index 0000000000..4a05868a48 --- /dev/null +++ b/src/cssutils/css/cssnamespacerule.py @@ -0,0 +1,306 @@ +"""CSSNamespaceRule currently implements +http://dev.w3.org/csswg/css3-namespace/ + +(until 0.9.5a2: http://www.w3.org/TR/2006/WD-css3-namespace-20060828/) +""" +__all__ = ['CSSNamespaceRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssnamespacerule.py 1305 2008-06-22 18:42:51Z cthedot $' + +import xml.dom +import cssrule +import cssutils +from cssutils.helper import Deprecated + +class CSSNamespaceRule(cssrule.CSSRule): + """ + Represents an @namespace rule within a CSS style sheet. + + The @namespace at-rule declares a namespace prefix and associates + it with a given namespace (a string). This namespace prefix can then be + used in namespace-qualified names such as those described in the + Selectors Module [SELECT] or the Values and Units module [CSS3VAL]. + + Properties + ========== + atkeyword (cssutils only) + the literal keyword used + cssText: of type DOMString + The parsable textual representation of this rule + namespaceURI: of type DOMString + The namespace URI (a simple string!) which is bound to the given + prefix. If no prefix is set (``CSSNamespaceRule.prefix==''``) + the namespace defined by ``namespaceURI`` is set as the default + namespace. + prefix: of type DOMString + The prefix used in the stylesheet for the given + ``CSSNamespaceRule.nsuri``. If prefix is empty namespaceURI sets a + default namespace for the stylesheet. + + Inherits properties from CSSRule + + Format + ====== + namespace + : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* + ; + namespace_prefix + : IDENT + ; + """ + type = property(lambda self: cssrule.CSSRule.NAMESPACE_RULE) + + def __init__(self, namespaceURI=None, prefix=None, cssText=None, + parentRule=None, parentStyleSheet=None, readonly=False): + """ + :Parameters: + namespaceURI + The namespace URI (a simple string!) which is bound to the + given prefix. If no prefix is set + (``CSSNamespaceRule.prefix==''``) the namespace defined by + namespaceURI is set as the default namespace + prefix + The prefix used in the stylesheet for the given + ``CSSNamespaceRule.uri``. + cssText + if no namespaceURI is given cssText must be given to set + a namespaceURI as this is readonly later on + parentStyleSheet + sheet where this rule belongs to + + Do not use as positional but as keyword parameters only! + + If readonly allows setting of properties in constructor only + + format namespace:: + + namespace + : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* + ; + namespace_prefix + : IDENT + ; + """ + super(CSSNamespaceRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = u'@namespace' + self._prefix = u'' + self._namespaceURI = None + + if namespaceURI: + self.namespaceURI = namespaceURI + self.prefix = prefix + tempseq = self._tempSeq() + tempseq.append(self.prefix, 'prefix') + tempseq.append(self.namespaceURI, 'namespaceURI') + self._setSeq(tempseq) + elif cssText is not None: + self.cssText = cssText + + if parentStyleSheet: + self._parentStyleSheet = parentStyleSheet + + self._readonly = readonly + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_CSSNamespaceRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + :param cssText: initial value for this rules cssText which is parsed + :Exceptions: + - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - `INVALID_MODIFICATION_ERR`: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule) + Raised if the rule is readonly. + - `SYNTAX_ERR`: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + """ + super(CSSNamespaceRule, self)._setCssText(cssText) + tokenizer = self._tokenize2(cssText) + attoken = self._nexttoken(tokenizer, None) + if self._type(attoken) != self._prods.NAMESPACE_SYM: + self._log.error(u'CSSNamespaceRule: No CSSNamespaceRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + # for closures: must be a mutable + new = {'keyword': self._tokenvalue(attoken), + 'prefix': u'', + 'uri': None, + 'wellformed': True + } + + def _ident(expected, seq, token, tokenizer=None): + # the namespace prefix, optional + if 'prefix or uri' == expected: + new['prefix'] = self._tokenvalue(token) + seq.append(new['prefix'], 'prefix') + return 'uri' + else: + new['wellformed'] = False + self._log.error( + u'CSSNamespaceRule: Unexpected ident.', token) + return expected + + def _string(expected, seq, token, tokenizer=None): + # the namespace URI as a STRING + if expected.endswith('uri'): + new['uri'] = self._stringtokenvalue(token) + seq.append(new['uri'], 'namespaceURI') + return ';' + + else: + new['wellformed'] = False + self._log.error( + u'CSSNamespaceRule: Unexpected string.', token) + return expected + + def _uri(expected, seq, token, tokenizer=None): + # the namespace URI as URI which is DEPRECATED + if expected.endswith('uri'): + uri = self._uritokenvalue(token) + new['uri'] = uri + seq.append(new['uri'], 'namespaceURI') + return ';' + else: + new['wellformed'] = False + self._log.error( + u'CSSNamespaceRule: Unexpected URI.', token) + return expected + + def _char(expected, seq, token, tokenizer=None): + # final ; + val = self._tokenvalue(token) + if ';' == expected and u';' == val: + return 'EOF' + else: + new['wellformed'] = False + self._log.error( + u'CSSNamespaceRule: Unexpected char.', token) + return expected + + # "NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*" + newseq = self._tempSeq() + wellformed, expected = self._parse(expected='prefix or uri', + seq=newseq, tokenizer=tokenizer, + productions={'IDENT': _ident, + 'STRING': _string, + 'URI': _uri, + 'CHAR': _char}, + new=new) + + # wellformed set by parse + wellformed = wellformed and new['wellformed'] + + # post conditions + if new['uri'] is None: + wellformed = False + self._log.error(u'CSSNamespaceRule: No namespace URI found: %s' % + self._valuestr(cssText)) + + if expected != 'EOF': + wellformed = False + self._log.error(u'CSSNamespaceRule: No ";" found: %s' % + self._valuestr(cssText)) + + # set all + if wellformed: + self.atkeyword = new['keyword'] + self._prefix = new['prefix'] + self.namespaceURI = new['uri'] + self._setSeq(newseq) + + cssText = property(fget=_getCssText, fset=_setCssText, + doc="(DOM attribute) The parsable textual representation.") + + def _setNamespaceURI(self, namespaceURI): + """ + DOMException on setting + + :param namespaceURI: the initial value for this rules namespaceURI + :Exceptions: + - `NO_MODIFICATION_ALLOWED_ERR`: + (CSSRule) Raised if this rule is readonly or a namespaceURI is + already set in this rule. + """ + self._checkReadonly() + if not self._namespaceURI: + # initial setting + self._namespaceURI = namespaceURI + tempseq = self._tempSeq() + tempseq.append(namespaceURI, 'namespaceURI') + self._setSeq(tempseq) # makes seq readonly! + elif self._namespaceURI != namespaceURI: + self._log.error(u'CSSNamespaceRule: namespaceURI is readonly.', + error=xml.dom.NoModificationAllowedErr) + + namespaceURI = property(lambda self: self._namespaceURI, _setNamespaceURI, + doc="URI (string!) of the defined namespace.") + + def _setPrefix(self, prefix=None): + """ + DOMException on setting + + :param prefix: the new prefix + :Exceptions: + - `SYNTAX_ERR`: (TODO) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - `NO_MODIFICATION_ALLOWED_ERR`: CSSRule) + Raised if this rule is readonly. + """ + self._checkReadonly() + if not prefix: + prefix = u'' + else: + tokenizer = self._tokenize2(prefix) + prefixtoken = self._nexttoken(tokenizer, None) + if not prefixtoken or self._type(prefixtoken) != self._prods.IDENT: + self._log.error(u'CSSNamespaceRule: No valid prefix "%s".' % + self._valuestr(prefix), + error=xml.dom.SyntaxErr) + return + else: + prefix = self._tokenvalue(prefixtoken) + # update seg + for i, x in enumerate(self._seq): + if x == self._prefix: + self._seq[i] = (prefix, 'prefix', None, None) + break + else: + # put prefix at the beginning! + self._seq[0] = (prefix, 'prefix', None, None) + + # set new prefix + self._prefix = prefix + + prefix = property(lambda self: self._prefix, _setPrefix, + doc="Prefix used for the defined namespace.") + +# def _setParentStyleSheet(self, parentStyleSheet): +# self._parentStyleSheet = parentStyleSheet +# +# parentStyleSheet = property(lambda self: self._parentStyleSheet, +# _setParentStyleSheet, +# doc=u"Containing CSSStyleSheet.") + + wellformed = property(lambda self: self.namespaceURI is not None) + + def __repr__(self): + return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % ( + self.__class__.__name__, self.namespaceURI, self.prefix) + + def __str__(self): + return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % ( + self.__class__.__name__, self.namespaceURI, self.prefix, id(self)) diff --git a/src/cssutils/css/csspagerule.py b/src/cssutils/css/csspagerule.py new file mode 100644 index 0000000000..e042d2b672 --- /dev/null +++ b/src/cssutils/css/csspagerule.py @@ -0,0 +1,286 @@ +"""CSSPageRule implements DOM Level 2 CSS CSSPageRule. +""" +__all__ = ['CSSPageRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: csspagerule.py 1284 2008-06-05 16:29:17Z cthedot $' + +import xml.dom +import cssrule +import cssutils +from selectorlist import SelectorList +from cssstyledeclaration import CSSStyleDeclaration + +class CSSPageRule(cssrule.CSSRule): + """ + The CSSPageRule interface represents a @page rule within a CSS style + sheet. The @page rule is used to specify the dimensions, orientation, + margins, etc. of a page box for paged media. + + Properties + ========== + atkeyword (cssutils only) + the literal keyword used + cssText: of type DOMString + The parsable textual representation of this rule + selectorText: of type DOMString + The parsable textual representation of the page selector for the rule. + style: of type CSSStyleDeclaration + The declaration-block of this rule. + + Inherits properties from CSSRule + + Format + ====== + :: + + page + : PAGE_SYM S* pseudo_page? S* + LBRACE S* declaration [ ';' S* declaration ]* '}' S* + ; + pseudo_page + : ':' IDENT # :first, :left, :right in CSS 2.1 + ; + + """ + type = property(lambda self: cssrule.CSSRule.PAGE_RULE) + # constant but needed: + wellformed = True + + def __init__(self, selectorText=None, style=None, parentRule=None, + parentStyleSheet=None, readonly=False): + """ + if readonly allows setting of properties in constructor only + + selectorText + type string + style + CSSStyleDeclaration for this CSSStyleRule + """ + super(CSSPageRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = u'@page' + tempseq = self._tempSeq() + if selectorText: + self.selectorText = selectorText + tempseq.append(self.selectorText, 'selectorText') + else: + self._selectorText = u'' + if style: + self.style = style + tempseq.append(self.style, 'style') + else: + self._style = CSSStyleDeclaration(parentRule=self) + self._setSeq(tempseq) + + self._readonly = readonly + + def __parseSelectorText(self, selectorText): + """ + parses selectorText which may also be a list of tokens + and returns (selectorText, seq) + + see _setSelectorText for details + """ + # for closures: must be a mutable + new = {'selector': None, 'wellformed': True} + + def _char(expected, seq, token, tokenizer=None): + # pseudo_page, :left, :right or :first + val = self._tokenvalue(token) + if ':' == expected and u':' == val: + try: + identtoken = tokenizer.next() + except StopIteration: + self._log.error( + u'CSSPageRule selectorText: No IDENT found.', token) + else: + ival, ityp = self._tokenvalue(identtoken), self._type(identtoken) + if self._prods.IDENT != ityp: + self._log.error( + u'CSSPageRule selectorText: Expected IDENT but found: %r' % + ival, token) + else: + new['selector'] = val + ival + seq.append(new['selector'], 'selector') + return 'EOF' + return expected + else: + new['wellformed'] = False + self._log.error( + u'CSSPageRule selectorText: Unexpected CHAR: %r' % val, token) + return expected + + def S(expected, seq, token, tokenizer=None): + "Does not raise if EOF is found." + return expected + + def COMMENT(expected, seq, token, tokenizer=None): + "Does not raise if EOF is found." + seq.append(cssutils.css.CSSComment([token]), 'COMMENT') + return expected + + newseq = self._tempSeq() + wellformed, expected = self._parse(expected=':', + seq=newseq, tokenizer=self._tokenize2(selectorText), + productions={'CHAR': _char, + 'COMMENT': COMMENT, + 'S': S}, + new=new) + wellformed = wellformed and new['wellformed'] + newselector = new['selector'] + + # post conditions + if expected == 'ident': + self._log.error( + u'CSSPageRule selectorText: No valid selector: %r' % + self._valuestr(selectorText)) + + if not newselector in (None, u':first', u':left', u':right'): + self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: %r' % + newselector, neverraise=True) + + return newselector, newseq + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_CSSPageRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - SYNTAX_ERR: (self, StyleDeclaration) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - HIERARCHY_REQUEST_ERR: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSPageRule, self)._setCssText(cssText) + + tokenizer = self._tokenize2(cssText) + if self._type(self._nexttoken(tokenizer)) != self._prods.PAGE_SYM: + self._log.error(u'CSSPageRule: No CSSPageRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + wellformed = True + selectortokens, startbrace = self._tokensupto2(tokenizer, + blockstartonly=True, + separateEnd=True) + styletokens, braceorEOFtoken = self._tokensupto2(tokenizer, + blockendonly=True, + separateEnd=True) + nonetoken = self._nexttoken(tokenizer) + if self._tokenvalue(startbrace) != u'{': + wellformed = False + self._log.error( + u'CSSPageRule: No start { of style declaration found: %r' % + self._valuestr(cssText), startbrace) + elif nonetoken: + wellformed = False + self._log.error( + u'CSSPageRule: Trailing content found.', token=nonetoken) + + + newselector, newselectorseq = self.__parseSelectorText(selectortokens) + + newstyle = CSSStyleDeclaration() + val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken) + if val != u'}' and typ != 'EOF': + wellformed = False + self._log.error( + u'CSSPageRule: No "}" after style declaration found: %r' % + self._valuestr(cssText)) + else: + if 'EOF' == typ: + # add again as style needs it + styletokens.append(braceorEOFtoken) + newstyle.cssText = styletokens + + if wellformed: + self._selectorText = newselector # already parsed + self.style = newstyle + self._setSeq(newselectorseq) # contains upto style only + + cssText = property(_getCssText, _setCssText, + doc="(DOM) The parsable textual representation of the rule.") + + def _getSelectorText(self): + """ + wrapper for cssutils Selector object + """ + return self._selectorText + + def _setSelectorText(self, selectorText): + """ + wrapper for cssutils Selector object + + selector: DOM String + in CSS 2.1 one of + - :first + - :left + - :right + - empty + + If WS or Comments are included they are ignored here! Only + way to add a comment is via setting ``cssText`` + + DOMException on setting + + - SYNTAX_ERR: + Raised if the specified CSS string value has a syntax error + and is unparsable. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this rule is readonly. + """ + self._checkReadonly() + + # may raise SYNTAX_ERR + newselectortext, newseq = self.__parseSelectorText(selectorText) + + if newselectortext: + for i, x in enumerate(self.seq): + if x == self._selectorText: + self.seq[i] = newselectortext + self._selectorText = newselectortext + + selectorText = property(_getSelectorText, _setSelectorText, + doc="""(DOM) The parsable textual representation of the page selector for the rule.""") + + def _getStyle(self): + + return self._style + + def _setStyle(self, style): + """ + style + StyleDeclaration or string + """ + self._checkReadonly() + + if isinstance(style, basestring): + self._style.cssText = style + else: + # cssText would be serialized with optional preferences + # so use seq! + self._style._seq = style.seq + + style = property(_getStyle, _setStyle, + doc="(DOM) The declaration-block of this rule set.") + + def __repr__(self): + return "cssutils.css.%s(selectorText=%r, style=%r)" % ( + self.__class__.__name__, self.selectorText, self.style.cssText) + + def __str__(self): + return "<cssutils.css.%s object selectorText=%r style=%r at 0x%x>" % ( + self.__class__.__name__, self.selectorText, self.style.cssText, + id(self)) diff --git a/src/cssutils/css/cssproperties.py b/src/cssutils/css/cssproperties.py new file mode 100644 index 0000000000..bc253b3e3d --- /dev/null +++ b/src/cssutils/css/cssproperties.py @@ -0,0 +1,349 @@ +"""CSS2Properties (partly!) implements DOM Level 2 CSS CSS2Properties used +by CSSStyleDeclaration + +TODO: CSS2Properties + If an implementation does implement this interface, it is expected to + understand the specific syntax of the shorthand properties, and apply + their semantics; when the margin property is set, for example, the + marginTop, marginRight, marginBottom and marginLeft properties are + actually being set by the underlying implementation. + + When dealing with CSS "shorthand" properties, the shorthand properties + should be decomposed into their component longhand properties as + appropriate, and when querying for their value, the form returned + should be the shortest form exactly equivalent to the declarations made + in the ruleset. However, if there is no shorthand declaration that + could be added to the ruleset without changing in any way the rules + already declared in the ruleset (i.e., by adding longhand rules that + were previously not declared in the ruleset), then the empty string + should be returned for the shorthand property. + + For example, querying for the font property should not return + "normal normal normal 14pt/normal Arial, sans-serif", when + "14pt Arial, sans-serif" suffices. (The normals are initial values, and + are implied by use of the longhand property.) + + If the values for all the longhand properties that compose a particular + string are the initial values, then a string consisting of all the + initial values should be returned (e.g. a border-width value of + "medium" should be returned as such, not as ""). + + For some shorthand properties that take missing values from other + sides, such as the margin, padding, and border-[width|style|color] + properties, the minimum number of sides possible should be used; i.e., + "0px 10px" will be returned instead of "0px 10px 0px 10px". + + If the value of a shorthand property can not be decomposed into its + component longhand properties, as is the case for the font property + with a value of "menu", querying for the values of the component + longhand properties should return the empty string. + +TODO: CSS2Properties DOMImplementation + The interface found within this section are not mandatory. A DOM + application can use the hasFeature method of the DOMImplementation + interface to determine whether it is supported or not. The feature + string for this extended interface listed in this section is "CSS2" + and the version is "2.0". + + +cssvalues +========= +contributed by Kevin D. Smith, thanks! + +"cssvalues" is used as a property validator. +it is an importable object that contains a dictionary of compiled regular +expressions. The keys of this dictionary are all of the valid CSS property +names. The values are compiled regular expressions that can be used to +validate the values for that property. (Actually, the values are references +to the 'match' method of a compiled regular expression, so that they are +simply called like functions.) + +""" +__all__ = ['CSS2Properties', 'cssvalues'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssproperties.py 1469 2008-09-15 19:06:00Z cthedot $' + +import re + +""" +Define some regular expression fragments that will be used as +macros within the CSS property value regular expressions. +""" +MACROS = { + 'ident': r'[-]?{nmstart}{nmchar}*', + 'name': r'{nmchar}+', + 'nmstart': r'[_a-z]|{nonascii}|{escape}', + 'nonascii': r'[^\0-\177]', + 'unicode': r'\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?', + 'escape': r'{unicode}|\\[ -~\200-\777]', +# 'escape': r'{unicode}|\\[ -~\200-\4177777]', + 'int': r'[-]?\d+', + 'nmchar': r'[\w-]|{nonascii}|{escape}', + 'num': r'[-]?\d+|[-]?\d*\.\d+', + 'number': r'{num}', + 'string': r'{string1}|{string2}', + 'string1': r'"(\\\"|[^\"])*"', + 'string2': r"'(\\\'|[^\'])*'", + 'nl': r'\n|\r\n|\r|\f', + 'w': r'\s*', + + 'integer': r'{int}', + 'length': r'0|{num}(em|ex|px|in|cm|mm|pt|pc)', + 'angle': r'0|{num}(deg|grad|rad)', + 'time': r'0|{num}m?s', + 'frequency': r'0|{num}k?Hz', + 'color': r'(maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)|#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)', + 'uri': r'url\({w}({string}|(\\\)|[^\)])+){w}\)', + 'percentage': r'{num}%', + 'border-style': 'none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset', + 'border-color': '{color}', + 'border-width': '{length}|thin|medium|thick', + + 'background-color': r'{color}|transparent|inherit', + 'background-image': r'{uri}|none|inherit', + 'background-position': r'({percentage}|{length})(\s*({percentage}|{length}))?|((top|center|bottom)\s*(left|center|right))|((left|center|right)\s*(top|center|bottom))|inherit', + 'background-repeat': r'repeat|repeat-x|repeat-y|no-repeat|inherit', + 'background-attachment': r'scroll|fixed|inherit', + + 'shape': r'rect\(({w}({length}|auto}){w},){3}{w}({length}|auto){w}\)', + 'counter': r'counter\({w}{identifier}{w}(?:,{w}{list-style-type}{w})?\)', + 'identifier': r'{ident}', + 'family-name': r'{string}|{identifier}', + 'generic-family': r'serif|sans-serif|cursive|fantasy|monospace', + 'absolute-size': r'(x?x-)?(small|large)|medium', + 'relative-size': r'smaller|larger', + 'font-family': r'(({family-name}|{generic-family}){w},{w})*({family-name}|{generic-family})|inherit', + 'font-size': r'{absolute-size}|{relative-size}|{length}|{percentage}|inherit', + 'font-style': r'normal|italic|oblique|inherit', + 'font-variant': r'normal|small-caps|inherit', + 'font-weight': r'normal|bold|bolder|lighter|[1-9]00|inherit', + 'line-height': r'normal|{number}|{length}|{percentage}|inherit', + 'list-style-image': r'{uri}|none|inherit', + 'list-style-position': r'inside|outside|inherit', + 'list-style-type': r'disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman|lower-greek|lower-(latin|alpha)|upper-(latin|alpha)|armenian|georgian|none|inherit', + 'margin-width': r'{length}|{percentage}|auto', + 'outline-color': r'{color}|invert|inherit', + 'outline-style': r'{border-style}|inherit', + 'outline-width': r'{border-width}|inherit', + 'padding-width': r'{length}|{percentage}', + 'specific-voice': r'{identifier}', + 'generic-voice': r'male|female|child', + 'content': r'{string}|{uri}|{counter}|attr\({w}{identifier}{w}\)|open-quote|close-quote|no-open-quote|no-close-quote', + 'border-attrs': r'{border-width}|{border-style}|{border-color}', + 'background-attrs': r'{background-color}|{background-image}|{background-repeat}|{background-attachment}|{background-position}', + 'list-attrs': r'{list-style-type}|{list-style-position}|{list-style-image}', + 'font-attrs': r'{font-style}|{font-variant}|{font-weight}', + 'outline-attrs': r'{outline-color}|{outline-style}|{outline-width}', + 'text-attrs': r'underline|overline|line-through|blink', +} + +""" +Define the regular expressions for validation all CSS values +""" +cssvalues = { + 'azimuth': r'{angle}|(behind\s+)?(left-side|far-left|left|center-left|center|center-right|right|far-right|right-side)(\s+behind)?|behind|leftwards|rightwards|inherit', + 'background-attachment': r'{background-attachment}', + 'background-color': r'{background-color}', + 'background-image': r'{background-image}', + 'background-position': r'{background-position}', + 'background-repeat': r'{background-repeat}', + # Each piece should only be allowed one time + 'background': r'{background-attrs}(\s+{background-attrs})*|inherit', + 'border-collapse': r'collapse|separate|inherit', + 'border-color': r'({border-color}|transparent)(\s+({border-color}|transparent)){0,3}|inherit', + 'border-spacing': r'{length}(\s+{length})?|inherit', + 'border-style': r'{border-style}(\s+{border-style}){0,3}|inherit', + 'border-top': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-right': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-bottom': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-left': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-top-color': r'{border-color}|transparent|inherit', + 'border-right-color': r'{border-color}|transparent|inherit', + 'border-bottom-color': r'{border-color}|transparent|inherit', + 'border-left-color': r'{border-color}|transparent|inherit', + 'border-top-style': r'{border-style}|inherit', + 'border-right-style': r'{border-style}|inherit', + 'border-bottom-style': r'{border-style}|inherit', + 'border-left-style': r'{border-style}|inherit', + 'border-top-width': r'{border-width}|inherit', + 'border-right-width': r'{border-width}|inherit', + 'border-bottom-width': r'{border-width}|inherit', + 'border-left-width': r'{border-width}|inherit', + 'border-width': r'{border-width}(\s+{border-width}){0,3}|inherit', + 'border': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'bottom': r'{length}|{percentage}|auto|inherit', + 'caption-side': r'top|bottom|inherit', + 'clear': r'none|left|right|both|inherit', + 'clip': r'{shape}|auto|inherit', + 'color': r'{color}|inherit', + 'content': r'normal|{content}(\s+{content})*|inherit', + 'counter-increment': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit', + 'counter-reset': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit', + 'cue-after': r'{uri}|none|inherit', + 'cue-before': r'{uri}|none|inherit', + 'cue': r'({uri}|none|inherit){1,2}|inherit', + 'cursor': r'((({uri}{w},{w})*)?(auto|crosshair|default|pointer|move|(e|ne|nw|n|se|sw|s|w)-resize|text|wait|help|progress))|inherit', + 'direction': r'ltr|rtl|inherit', + 'display': r'inline|block|list-item|run-in|inline-block|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|none|inherit', + 'elevation': r'{angle}|below|level|above|higher|lower|inherit', + 'empty-cells': r'show|hide|inherit', + 'float': r'left|right|none|inherit', + 'font-family': r'{font-family}', + 'font-size': r'{font-size}', + 'font-style': r'{font-style}', + 'font-variant': r'{font-variant}', + 'font-weight': r'{font-weight}', + 'font': r'({font-attrs}\s+)*{font-size}({w}/{w}{line-height})?\s+{font-family}|caption|icon|menu|message-box|small-caption|status-bar|inherit', + 'height': r'{length}|{percentage}|auto|inherit', + 'left': r'{length}|{percentage}|auto|inherit', + 'letter-spacing': r'normal|{length}|inherit', + 'line-height': r'{line-height}', + 'list-style-image': r'{list-style-image}', + 'list-style-position': r'{list-style-position}', + 'list-style-type': r'{list-style-type}', + 'list-style': r'{list-attrs}(\s+{list-attrs})*|inherit', + 'margin-right': r'{margin-width}|inherit', + 'margin-left': r'{margin-width}|inherit', + 'margin-top': r'{margin-width}|inherit', + 'margin-bottom': r'{margin-width}|inherit', + 'margin': r'{margin-width}(\s+{margin-width}){0,3}|inherit', + 'max-height': r'{length}|{percentage}|none|inherit', + 'max-width': r'{length}|{percentage}|none|inherit', + 'min-height': r'{length}|{percentage}|none|inherit', + 'min-width': r'{length}|{percentage}|none|inherit', + 'orphans': r'{integer}|inherit', + 'outline-color': r'{outline-color}', + 'outline-style': r'{outline-style}', + 'outline-width': r'{outline-width}', + 'outline': r'{outline-attrs}(\s+{outline-attrs})*|inherit', + 'overflow': r'visible|hidden|scroll|auto|inherit', + 'padding-top': r'{padding-width}|inherit', + 'padding-right': r'{padding-width}|inherit', + 'padding-bottom': r'{padding-width}|inherit', + 'padding-left': r'{padding-width}|inherit', + 'padding': r'{padding-width}(\s+{padding-width}){0,3}|inherit', + 'page-break-after': r'auto|always|avoid|left|right|inherit', + 'page-break-before': r'auto|always|avoid|left|right|inherit', + 'page-break-inside': r'avoid|auto|inherit', + 'pause-after': r'{time}|{percentage}|inherit', + 'pause-before': r'{time}|{percentage}|inherit', + 'pause': r'({time}|{percentage}){1,2}|inherit', + 'pitch-range': r'{number}|inherit', + 'pitch': r'{frequency}|x-low|low|medium|high|x-high|inherit', + 'play-during': r'{uri}(\s+(mix|repeat))*|auto|none|inherit', + 'position': r'static|relative|absolute|fixed|inherit', + 'quotes': r'({string}\s+{string})(\s+{string}\s+{string})*|none|inherit', + 'richness': r'{number}|inherit', + 'right': r'{length}|{percentage}|auto|inherit', + 'speak-header': r'once|always|inherit', + 'speak-numeral': r'digits|continuous|inherit', + 'speak-punctuation': r'code|none|inherit', + 'speak': r'normal|none|spell-out|inherit', + 'speech-rate': r'{number}|x-slow|slow|medium|fast|x-fast|faster|slower|inherit', + 'stress': r'{number}|inherit', + 'table-layout': r'auto|fixed|inherit', + 'text-align': r'left|right|center|justify|inherit', + 'text-decoration': r'none|{text-attrs}(\s+{text-attrs})*|inherit', + 'text-indent': r'{length}|{percentage}|inherit', + 'text-transform': r'capitalize|uppercase|lowercase|none|inherit', + 'top': r'{length}|{percentage}|auto|inherit', + 'unicode-bidi': r'normal|embed|bidi-override|inherit', + 'vertical-align': r'baseline|sub|super|top|text-top|middle|bottom|text-bottom|{percentage}|{length}|inherit', + 'visibility': r'visible|hidden|collapse|inherit', + 'voice-family': r'({specific-voice}|{generic-voice}{w},{w})*({specific-voice}|{generic-voice})|inherit', + 'volume': r'{number}|{percentage}|silent|x-soft|soft|medium|loud|x-loud|inherit', + 'white-space': r'normal|pre|nowrap|pre-wrap|pre-line|inherit', + 'widows': r'{integer}|inherit', + 'width': r'{length}|{percentage}|auto|inherit', + 'word-spacing': r'normal|{length}|inherit', + 'z-index': r'auto|{integer}|inherit', +} + +def _expand_macros(tokdict): + """ Expand macros in token dictionary """ + def macro_value(m): + return '(?:%s)' % MACROS[m.groupdict()['macro']] + for key, value in tokdict.items(): + while re.search(r'{[a-z][a-z0-9-]*}', value): + value = re.sub(r'{(?P<macro>[a-z][a-z0-9-]*)}', + macro_value, value) + tokdict[key] = value + return tokdict + +def _compile_regexes(tokdict): + """ Compile all regular expressions into callable objects """ + for key, value in tokdict.items(): + tokdict[key] = re.compile('^(?:%s)$' % value, re.I).match + return tokdict + +_compile_regexes(_expand_macros(cssvalues)) + + +# functions to convert between CSS and DOM name + +_reCSStoDOMname = re.compile('-[a-z]', re.I) +def _toDOMname(CSSname): + """ + returns DOMname for given CSSname e.g. for CSSname 'font-style' returns + 'fontStyle' + """ + def _doCSStoDOMname2(m): return m.group(0)[1].capitalize() + return _reCSStoDOMname.sub(_doCSStoDOMname2, CSSname) + +_reDOMtoCSSname = re.compile('([A-Z])[a-z]+') +def _toCSSname(DOMname): + """ + returns CSSname for given DOMname e.g. for DOMname 'fontStyle' returns + 'font-style' + """ + def _doDOMtoCSSname2(m): return '-' + m.group(0).lower() + return _reDOMtoCSSname.sub(_doDOMtoCSSname2, DOMname) + + +class CSS2Properties(object): + """ + The CSS2Properties interface represents a convenience mechanism + for retrieving and setting properties within a CSSStyleDeclaration. + The attributes of this interface correspond to all the properties + specified in CSS2. Getting an attribute of this interface is + equivalent to calling the getPropertyValue method of the + CSSStyleDeclaration interface. Setting an attribute of this + interface is equivalent to calling the setProperty method of the + CSSStyleDeclaration interface. + + cssutils actually also allows usage of ``del`` to remove a CSS property + from a CSSStyleDeclaration. + + This is an abstract class, the following functions need to be present + in inheriting class: + + - ``_getP`` + - ``_setP`` + - ``_delP`` + """ + # actual properties are set after the class definition! + def _getP(self, CSSname): pass + def _setP(self, CSSname, value): pass + def _delP(self, CSSname): pass + +# add list of DOMname properties to CSS2Properties +# used for CSSStyleDeclaration to check if allowed properties +# but somehow doubled, any better way? +CSS2Properties._properties = [_toDOMname(p) for p in cssvalues.keys()] + +# add CSS2Properties to CSSStyleDeclaration: +def __named_property_def(DOMname): + """ + closure to keep name known in each properties accessor function + DOMname is converted to CSSname here, so actual calls use CSSname + """ + CSSname = _toCSSname(DOMname) + def _get(self): return self._getP(CSSname) + def _set(self, value): self._setP(CSSname, value) + def _del(self): self._delP(CSSname) + return _get, _set, _del + +# add all CSS2Properties to CSSStyleDeclaration +for DOMname in CSS2Properties._properties: + setattr(CSS2Properties, DOMname, + property(*__named_property_def(DOMname))) diff --git a/src/cssutils/css/cssrule.py b/src/cssutils/css/cssrule.py new file mode 100644 index 0000000000..58cc16f537 --- /dev/null +++ b/src/cssutils/css/cssrule.py @@ -0,0 +1,134 @@ +"""CSSRule implements DOM Level 2 CSS CSSRule.""" +__all__ = ['CSSRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssrule.py 1177 2008-03-20 17:47:23Z cthedot $' + +import xml.dom +import cssutils + +class CSSRule(cssutils.util.Base2): + """ + Abstract base interface for any type of CSS statement. This includes + both rule sets and at-rules. An implementation is expected to preserve + all rules specified in a CSS style sheet, even if the rule is not + recognized by the parser. Unrecognized rules are represented using the + CSSUnknownRule interface. + + Properties + ========== + cssText: of type DOMString + The parsable textual representation of the rule. This reflects the + current state of the rule and not its initial value. + parentRule: of type CSSRule, readonly + If this rule is contained inside another rule (e.g. a style rule + inside an @media block), this is the containing rule. If this rule + is not nested inside any other rules, this returns None. + parentStyleSheet: of type CSSStyleSheet, readonly + The style sheet that contains this rule. + type: of type unsigned short, readonly + The type of the rule, as defined above. The expectation is that + binding-specific casting methods can be used to cast down from an + instance of the CSSRule interface to the specific derived interface + implied by the type. + + cssutils only + ------------- + seq (READONLY): + contains sequence of parts of the rule including comments but + excluding @KEYWORD and braces + typeString: string + A string name of the type of this rule, e.g. 'STYLE_RULE'. Mainly + useful for debugging + wellformed: + if a rule is valid + """ + + """ + CSSRule type constants. + An integer indicating which type of rule this is. + """ + COMMENT = -1 # cssutils only + UNKNOWN_RULE = 0 #u + STYLE_RULE = 1 #s + CHARSET_RULE = 2 #c + IMPORT_RULE = 3 #i + MEDIA_RULE = 4 #m + FONT_FACE_RULE = 5 #f + PAGE_RULE = 6 #p + NAMESPACE_RULE = 7 # CSSOM + + _typestrings = ['UNKNOWN_RULE', 'STYLE_RULE', 'CHARSET_RULE', 'IMPORT_RULE', + 'MEDIA_RULE', 'FONT_FACE_RULE', 'PAGE_RULE', 'NAMESPACE_RULE', + 'COMMENT'] + + type = UNKNOWN_RULE + """ + The type of this rule, as defined by a CSSRule type constant. + Overwritten in derived classes. + + The expectation is that binding-specific casting methods can be used to + cast down from an instance of the CSSRule interface to the specific + derived interface implied by the type. + (Casting not for this Python implementation I guess...) + """ + + def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False): + """ + set common attributes for all rules + """ + super(CSSRule, self).__init__() + self._parentRule = parentRule + self._parentStyleSheet = parentStyleSheet + self._setSeq(self._tempSeq()) + # must be set after initialization of #inheriting rule is done + self._readonly = False + + def _setCssText(self, cssText): + """ + DOMException on setting + + - SYNTAX_ERR: + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: + Raised if the specified CSS string value represents a different + type of rule than the current one. + - HIERARCHY_REQUEST_ERR: + Raised if the rule cannot be inserted at this point in the + style sheet. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if the rule is readonly. + """ + self._checkReadonly() + + cssText = property(lambda self: u'', _setCssText, + doc="""(DOM) The parsable textual representation of the rule. This + reflects the current state of the rule and not its initial value. + The initial value is saved, but this may be removed in a future + version! + MUST BE OVERWRITTEN IN SUBCLASS TO WORK!""") + + def _setAtkeyword(self, akw): + """checks if new keyword is normalized same as old""" + if not self.atkeyword or (self._normalize(akw) == + self._normalize(self.atkeyword)): + self._atkeyword = akw + else: + self._log.error(u'%s: Invalid atkeyword for this rule: %r' % + (self._normalize(self.atkeyword), akw), + error=xml.dom.InvalidModificationErr) + + atkeyword = property(lambda self: self._atkeyword, _setAtkeyword, + doc=u"@keyword for @rules") + + parentRule = property(lambda self: self._parentRule, + doc=u"READONLY") + + parentStyleSheet = property(lambda self: self._parentStyleSheet, + doc=u"READONLY") + + wellformed = property(lambda self: False, + doc=u"READONLY") + + typeString = property(lambda self: CSSRule._typestrings[self.type], + doc="Name of this rules type.") diff --git a/src/cssutils/css/cssrulelist.py b/src/cssutils/css/cssrulelist.py new file mode 100644 index 0000000000..fdc9f29caf --- /dev/null +++ b/src/cssutils/css/cssrulelist.py @@ -0,0 +1,60 @@ +""" +CSSRuleList implements DOM Level 2 CSS CSSRuleList. + +Partly also + * http://dev.w3.org/csswg/cssom/#the-cssrulelist +""" +__all__ = ['CSSRuleList'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssrulelist.py 1116 2008-03-05 13:52:23Z cthedot $' + +class CSSRuleList(list): + """ + The CSSRuleList object represents an (ordered) list of statements. + + The items in the CSSRuleList are accessible via an integral index, + starting from 0. + + Subclasses a standard Python list so theoretically all standard list + methods are available. Setting methods like ``__init__``, ``append``, + ``extend`` or ``__setslice__`` are added later on instances of this + class if so desired. + E.g. CSSStyleSheet adds ``append`` which is not available in a simple + instance of this class! + + Properties + ========== + length: of type unsigned long, readonly + The number of CSSRules in the list. The range of valid child rule + indices is 0 to length-1 inclusive. + """ + def __init__(self, *ignored): + "nothing is set as this must also be defined later" + pass + + def __notimplemented(self, *ignored): + "no direct setting possible" + raise NotImplementedError( + 'Must be implemented by class using an instance of this class.') + + append = extend = __setitem__ = __setslice__ = __notimplemented + + def item(self, index): + """ + (DOM) + Used to retrieve a CSS rule by ordinal index. The order in this + collection represents the order of the rules in the CSS style + sheet. If index is greater than or equal to the number of rules in + the list, this returns None. + + Returns CSSRule, the style rule at the index position in the + CSSRuleList, or None if that is not a valid index. + """ + try: + return self[index] + except IndexError: + return None + + length = property(lambda self: len(self), + doc="(DOM) The number of CSSRules in the list.") + diff --git a/src/cssutils/css/cssstyledeclaration.py b/src/cssutils/css/cssstyledeclaration.py new file mode 100644 index 0000000000..43eda2049b --- /dev/null +++ b/src/cssutils/css/cssstyledeclaration.py @@ -0,0 +1,651 @@ +"""CSSStyleDeclaration implements DOM Level 2 CSS CSSStyleDeclaration and +extends CSS2Properties + +see + http://www.w3.org/TR/1998/REC-CSS2-19980512/syndata.html#parsing-errors + +Unknown properties +------------------ +User agents must ignore a declaration with an unknown property. +For example, if the style sheet is:: + + H1 { color: red; rotation: 70minutes } + +the user agent will treat this as if the style sheet had been:: + + H1 { color: red } + +Cssutils gives a message about any unknown properties but +keeps any property (if syntactically correct). + +Illegal values +-------------- +User agents must ignore a declaration with an illegal value. For example:: + + IMG { float: left } /* correct CSS2 */ + IMG { float: left here } /* "here" is not a value of 'float' */ + IMG { background: "red" } /* keywords cannot be quoted in CSS2 */ + IMG { border-width: 3 } /* a unit must be specified for length values */ + +A CSS2 parser would honor the first rule and ignore the rest, as if the +style sheet had been:: + + IMG { float: left } + IMG { } + IMG { } + IMG { } + +Cssutils again will issue a message (WARNING in this case) about invalid +CSS2 property values. + +TODO: + This interface is also used to provide a read-only access to the + computed values of an element. See also the ViewCSS interface. + + - return computed values and not literal values + - simplify unit pairs/triples/quadruples + 2px 2px 2px 2px -> 2px for border/padding... + - normalize compound properties like: + background: no-repeat left url() #fff + -> background: #fff url() no-repeat left +""" +__all__ = ['CSSStyleDeclaration', 'Property'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssstyledeclaration.py 1284 2008-06-05 16:29:17Z cthedot $' + +import xml.dom +import cssutils +from cssproperties import CSS2Properties +from property import Property + +class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2): + """ + The CSSStyleDeclaration class represents a single CSS declaration + block. This class may be used to determine the style properties + currently set in a block or to set style properties explicitly + within the block. + + While an implementation may not recognize all CSS properties within + a CSS declaration block, it is expected to provide access to all + specified properties in the style sheet through the + CSSStyleDeclaration interface. + Furthermore, implementations that support a specific level of CSS + should correctly handle CSS shorthand properties for that level. For + a further discussion of shorthand properties, see the CSS2Properties + interface. + + Additionally the CSS2Properties interface is implemented. + + Properties + ========== + cssText + The parsable textual representation of the declaration block + (excluding the surrounding curly braces). Setting this attribute + will result in the parsing of the new value and resetting of the + properties in the declaration block. It also allows the insertion + of additional properties and their values into the block. + length: of type unsigned long, readonly + The number of properties that have been explicitly set in this + declaration block. The range of valid indices is 0 to length-1 + inclusive. + parentRule: of type CSSRule, readonly + The CSS rule that contains this declaration block or None if this + CSSStyleDeclaration is not attached to a CSSRule. + seq: a list (cssutils) + All parts of this style declaration including CSSComments + + $css2propertyname + All properties defined in the CSS2Properties class are available + as direct properties of CSSStyleDeclaration with their respective + DOM name, so e.g. ``fontStyle`` for property 'font-style'. + + These may be used as:: + + >>> style = CSSStyleDeclaration(cssText='color: red') + >>> style.color = 'green' + >>> print style.color + green + >>> del style.color + >>> print style.color # print empty string + + Format + ====== + [Property: Value Priority?;]* [Property: Value Priority?]? + """ + def __init__(self, cssText=u'', parentRule=None, readonly=False): + """ + cssText + Shortcut, sets CSSStyleDeclaration.cssText + parentRule + The CSS rule that contains this declaration block or + None if this CSSStyleDeclaration is not attached to a CSSRule. + readonly + defaults to False + """ + super(CSSStyleDeclaration, self).__init__() + self._parentRule = parentRule + #self._seq = self._tempSeq() + self.cssText = cssText + self._readonly = readonly + + def __contains__(self, nameOrProperty): + """ + checks if a property (or a property with given name is in style + + name + a string or Property, uses normalized name and not literalname + """ + if isinstance(nameOrProperty, Property): + name = nameOrProperty.name + else: + name = self._normalize(nameOrProperty) + return name in self.__nnames() + + def __iter__(self): + """ + iterator of set Property objects with different normalized names. + """ + def properties(): + for name in self.__nnames(): + yield self.getProperty(name) + return properties() + + def __setattr__(self, n, v): + """ + Prevent setting of unknown properties on CSSStyleDeclaration + which would not work anyway. For these + ``CSSStyleDeclaration.setProperty`` MUST be called explicitly! + + TODO: + implementation of known is not really nice, any alternative? + """ + known = ['_tokenizer', '_log', '_ttypes', + '_seq', 'seq', 'parentRule', '_parentRule', 'cssText', + 'valid', 'wellformed', + '_readonly'] + known.extend(CSS2Properties._properties) + if n in known: + super(CSSStyleDeclaration, self).__setattr__(n, v) + else: + raise AttributeError( + 'Unknown CSS Property, ``CSSStyleDeclaration.setProperty("%s", ...)`` MUST be used.' + % n) + + def __nnames(self): + """ + returns iterator for all different names in order as set + if names are set twice the last one is used (double reverse!) + """ + names = [] + for item in reversed(self.seq): + val = item.value + if isinstance(val, Property) and not val.name in names: + names.append(val.name) + return reversed(names) + + def __getitem__(self, CSSName): + """Retrieve the value of property ``CSSName`` from this declaration. + + ``CSSName`` will be always normalized. + """ + return self.getPropertyValue(CSSName) + + def __setitem__(self, CSSName, value): + """Set value of property ``CSSName``. ``value`` may also be a tuple of + (value, priority), e.g. style['color'] = ('red', 'important') + + ``CSSName`` will be always normalized. + """ + priority = None + if type(value) == tuple: + value, priority = value + + return self.setProperty(CSSName, value, priority) + + def __delitem__(self, CSSName): + """Delete property ``CSSName`` from this declaration. + If property is not in this declaration return u'' just like + removeProperty. + + ``CSSName`` will be always normalized. + """ + return self.removeProperty(CSSName) + + # overwritten accessor functions for CSS2Properties' properties + def _getP(self, CSSName): + """ + (DOM CSS2Properties) + Overwritten here and effectively the same as + ``self.getPropertyValue(CSSname)``. + + Parameter is in CSSname format ('font-style'), see CSS2Properties. + + Example:: + + >>> style = CSSStyleDeclaration(cssText='font-style:italic;') + >>> print style.fontStyle + italic + """ + return self.getPropertyValue(CSSName) + + def _setP(self, CSSName, value): + """ + (DOM CSS2Properties) + Overwritten here and effectively the same as + ``self.setProperty(CSSname, value)``. + + Only known CSS2Properties may be set this way, otherwise an + AttributeError is raised. + For these unknown properties ``setPropertyValue(CSSname, value)`` + has to be called explicitly. + Also setting the priority of properties needs to be done with a + call like ``setPropertyValue(CSSname, value, priority)``. + + Example:: + + >>> style = CSSStyleDeclaration() + >>> style.fontStyle = 'italic' + >>> # or + >>> style.setProperty('font-style', 'italic', '!important') + """ + self.setProperty(CSSName, value) + # TODO: Shorthand ones + + def _delP(self, CSSName): + """ + (cssutils only) + Overwritten here and effectively the same as + ``self.removeProperty(CSSname)``. + + Example:: + + >>> style = CSSStyleDeclaration(cssText='font-style:italic;') + >>> del style.fontStyle + >>> print style.fontStyle # prints u'' + + """ + self.removeProperty(CSSName) + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_css_CSSStyleDeclaration(self) + + def _setCssText(self, cssText): + """ + Setting this attribute will result in the parsing of the new value + and resetting of all the properties in the declaration block + including the removal or addition of properties. + + DOMException on setting + + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this declaration is readonly or a property is readonly. + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + """ + self._checkReadonly() + tokenizer = self._tokenize2(cssText) + + # for closures: must be a mutable + new = {'wellformed': True} + def ident(expected, seq, token, tokenizer=None): + # a property + + tokens = self._tokensupto2(tokenizer, starttoken=token, + semicolon=True) + if self._tokenvalue(tokens[-1]) == u';': + tokens.pop() + property = Property() + property.cssText = tokens + if property.wellformed: + seq.append(property, 'Property') + else: + self._log.error(u'CSSStyleDeclaration: Syntax Error in Property: %s' + % self._valuestr(tokens)) + # does not matter in this case + return expected + + def unexpected(expected, seq, token, tokenizer=None): + # error, find next ; or } to omit upto next property + ignored = self._tokenvalue(token) + self._valuestr( + self._tokensupto2(tokenizer, propertyvalueendonly=True)) + self._log.error(u'CSSStyleDeclaration: Unexpected token, ignoring upto %r.' % + ignored,token) + # does not matter in this case + return expected + + # [Property: Value;]* Property: Value? + newseq = self._tempSeq() + wellformed, expected = self._parse(expected=None, + seq=newseq, tokenizer=tokenizer, + productions={'IDENT': ident},#, 'CHAR': char}, + default=unexpected) + # wellformed set by parse + # post conditions + + # do not check wellformed as invalid things are removed anyway + #if wellformed: + self._setSeq(newseq) + + cssText = property(_getCssText, _setCssText, + doc="(DOM) A parsable textual representation of the declaration\ + block excluding the surrounding curly braces.") + + def getCssText(self, separator=None): + """ + returns serialized property cssText, each property separated by + given ``separator`` which may e.g. be u'' to be able to use + cssText directly in an HTML style attribute. ";" is always part of + each property (except the last one) and can **not** be set with + separator! + """ + return cssutils.ser.do_css_CSSStyleDeclaration(self, separator) + + def _getParentRule(self): + return self._parentRule + + def _setParentRule(self, parentRule): + self._parentRule = parentRule + + parentRule = property(_getParentRule, _setParentRule, + doc="(DOM) The CSS rule that contains this declaration block or\ + None if this CSSStyleDeclaration is not attached to a CSSRule.") + + def getProperties(self, name=None, all=False): + """ + Returns a list of Property objects set in this declaration. + + name + optional name of properties which are requested (a filter). + Only properties with this **always normalized** name are returned. + all=False + if False (DEFAULT) only the effective properties (the ones set + last) are returned. If name is given a list with only one property + is returned. + + if True all properties including properties set multiple times with + different values or priorities for different UAs are returned. + The order of the properties is fully kept as in the original + stylesheet. + """ + if name and not all: + # single prop but list + p = self.getProperty(name) + if p: + return [p] + else: + return [] + elif not all: + # effective Properties in name order + return [self.getProperty(name)for name in self.__nnames()] + else: + # all properties or all with this name + nname = self._normalize(name) + properties = [] + for item in self.seq: + val = item.value + if isinstance(val, Property) and ( + (bool(nname) == False) or (val.name == nname)): + properties.append(val) + return properties + + def getProperty(self, name, normalize=True): + """ + Returns the effective Property object. + + name + of the CSS property, always lowercase (even if not normalized) + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent + + If False may return **NOT** the effective value but the effective + for the unnormalized name. + """ + nname = self._normalize(name) + found = None + for item in reversed(self.seq): + val = item.value + if isinstance(val, Property): + if (normalize and nname == val.name) or name == val.literalname: + if val.priority: + return val + elif not found: + found = val + return found + + def getPropertyCSSValue(self, name, normalize=True): + """ + Returns CSSValue, the value of the effective property if it has been + explicitly set for this declaration block. + + name + of the CSS property, always lowercase (even if not normalized) + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent + + If False may return **NOT** the effective value but the effective + for the unnormalized name. + + (DOM) + Used to retrieve the object representation of the value of a CSS + property if it has been explicitly set within this declaration + block. Returns None if the property has not been set. + + (This method returns None if the property is a shorthand + property. Shorthand property values can only be accessed and + modified as strings, using the getPropertyValue and setProperty + methods.) + + **cssutils currently always returns a CSSValue if the property is + set.** + + for more on shorthand properties see + http://www.dustindiaz.com/css-shorthand/ + """ + nname = self._normalize(name) + if nname in self._SHORTHANDPROPERTIES: + self._log.info( + u'CSSValue for shorthand property "%s" should be None, this may be implemented later.' % + nname, neverraise=True) + + p = self.getProperty(name, normalize) + if p: + return p.cssValue + else: + return None + + def getPropertyValue(self, name, normalize=True): + """ + Returns the value of the effective property if it has been explicitly + set for this declaration block. Returns the empty string if the + property has not been set. + + name + of the CSS property, always lowercase (even if not normalized) + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent + + If False may return **NOT** the effective value but the effective + for the unnormalized name. + """ + p = self.getProperty(name, normalize) + if p: + return p.value + else: + return u'' + + def getPropertyPriority(self, name, normalize=True): + """ + Returns the priority of the effective CSS property (e.g. the + "important" qualifier) if the property has been explicitly set in + this declaration block. The empty string if none exists. + + name + of the CSS property, always lowercase (even if not normalized) + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent + + If False may return **NOT** the effective value but the effective + for the unnormalized name. + """ + p = self.getProperty(name, normalize) + if p: + return p.priority + else: + return u'' + + def removeProperty(self, name, normalize=True): + """ + (DOM) + Used to remove a CSS property if it has been explicitly set within + this declaration block. + + Returns the value of the property if it has been explicitly set for + this declaration block. Returns the empty string if the property + has not been set or the property name does not correspond to a + known CSS property + + name + of the CSS property + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent. + The effective Property value is returned and *all* Properties + with ``Property.name == name`` are removed. + + If False may return **NOT** the effective value but the effective + for the unnormalized ``name`` only. Also only the Properties with + the literal name ``name`` are removed. + + raises DOMException + + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this declaration is readonly or the property is + readonly. + """ + self._checkReadonly() + r = self.getPropertyValue(name, normalize=normalize) + newseq = self._tempSeq() + if normalize: + # remove all properties with name == nname + nname = self._normalize(name) + for item in self.seq: + if not (isinstance(item.value, Property) and item.value.name == nname): + newseq.appendItem(item) + else: + # remove all properties with literalname == name + for item in self.seq: + if not (isinstance(item.value, Property) and item.value.literalname == name): + newseq.appendItem(item) + self._setSeq(newseq) + return r + + def setProperty(self, name, value=None, priority=u'', normalize=True): + """ + (DOM) + Used to set a property value and priority within this declaration + block. + + name + of the CSS property to set (in W3C DOM the parameter is called + "propertyName"), always lowercase (even if not normalized) + + If a property with this name is present it will be reset + + cssutils also allowed name to be a Property object, all other + parameter are ignored in this case + + value + the new value of the property, omit if name is already a Property + priority + the optional priority of the property (e.g. "important") + normalize + if True (DEFAULT) name will be normalized (lowercase, no simple + escapes) so "color", "COLOR" or "C\olor" will all be equivalent + + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified value has a syntax error and is + unparsable. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this declaration is readonly or the property is + readonly. + """ + self._checkReadonly() + + if isinstance(name, Property): + newp = name + name = newp.literalname + else: + newp = Property(name, value, priority) + if not newp.wellformed: + self._log.warn(u'Invalid Property: %s: %s %s' + % (name, value, priority)) + else: + nname = self._normalize(name) + properties = self.getProperties(name, all=(not normalize)) + for property in reversed(properties): + if normalize and property.name == nname: + property.cssValue = newp.cssValue.cssText + property.priority = newp.priority + break + elif property.literalname == name: + property.cssValue = newp.cssValue.cssText + property.priority = newp.priority + break + else: + self.seq._readonly = False + self.seq.append(newp, 'Property') + self.seq._readonly = True + + def item(self, index): + """ + (DOM) + Used to retrieve the properties that have been explicitly set in + this declaration block. The order of the properties retrieved using + this method does not have to be the order in which they were set. + This method can be used to iterate over all properties in this + declaration block. + + index + of the property to retrieve, negative values behave like + negative indexes on Python lists, so -1 is the last element + + returns the name of the property at this ordinal position. The + empty string if no property exists at this position. + + ATTENTION: + Only properties with a different name are counted. If two + properties with the same name are present in this declaration + only the effective one is included. + + ``item()`` and ``length`` work on the same set here. + """ + names = list(self.__nnames()) + try: + return names[index] + except IndexError: + return u'' + + length = property(lambda self: len(self.__nnames()), + doc="(DOM) The number of distinct properties that have been explicitly\ + in this declaration block. The range of valid indices is 0 to\ + length-1 inclusive. These are properties with a different ``name``\ + only. ``item()`` and ``length`` work on the same set here.") + + def __repr__(self): + return "cssutils.css.%s(cssText=%r)" % ( + self.__class__.__name__, self.getCssText(separator=u' ')) + + def __str__(self): + return "<cssutils.css.%s object length=%r (all: %r) at 0x%x>" % ( + self.__class__.__name__, self.length, + len(self.getProperties(all=True)), id(self)) diff --git a/src/cssutils/css/cssstylerule.py b/src/cssutils/css/cssstylerule.py new file mode 100644 index 0000000000..e6dcfd0205 --- /dev/null +++ b/src/cssutils/css/cssstylerule.py @@ -0,0 +1,242 @@ +"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule. +""" +__all__ = ['CSSStyleRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssstylerule.py 1284 2008-06-05 16:29:17Z cthedot $' + +import xml.dom +import cssrule +import cssutils +from selectorlist import SelectorList +from cssstyledeclaration import CSSStyleDeclaration + +class CSSStyleRule(cssrule.CSSRule): + """ + The CSSStyleRule object represents a ruleset specified (if any) in a CSS + style sheet. It provides access to a declaration block as well as to the + associated group of selectors. + + Properties + ========== + selectorList: of type SelectorList (cssutils only) + A list of all Selector elements for the rule set. + selectorText: of type DOMString + The textual representation of the selector for the rule set. The + implementation may have stripped out insignificant whitespace while + parsing the selector. + style: of type CSSStyleDeclaration, (DOM) + The declaration-block of this rule set. + type + the type of this rule, constant cssutils.CSSRule.STYLE_RULE + + inherited properties: + - cssText + - parentRule + - parentStyleSheet + + Format + ====== + ruleset:: + + : selector [ COMMA S* selector ]* + LBRACE S* declaration [ ';' S* declaration ]* '}' S* + ; + """ + type = property(lambda self: cssrule.CSSRule.STYLE_RULE) + + def __init__(self, selectorText=None, style=None, parentRule=None, + parentStyleSheet=None, readonly=False): + """ + :Parameters: + selectorText + string parsed into selectorList + style + string parsed into CSSStyleDeclaration for this CSSStyleRule + readonly + if True allows setting of properties in constructor only + """ + super(CSSStyleRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + + self._selectorList = SelectorList(parentRule=self) + self._style = CSSStyleDeclaration(parentRule=self) + if selectorText: + self.selectorText = selectorText + if style: + self.style = style + + self._readonly = readonly + + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_CSSStyleRule(self) + + def _setCssText(self, cssText): + """ + :param cssText: + a parseable string or a tuple of (cssText, dict-of-namespaces) + :Exceptions: + - `NAMESPACE_ERR`: (Selector) + Raised if the specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (self, StyleDeclaration, etc) + Raised if the specified CSS string value has a syntax error and + is unparsable. + - `INVALID_MODIFICATION_ERR`: (self) + Raised if the specified CSS string value represents a different + type of rule than the current one. + - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet) + Raised if the rule cannot be inserted at this point in the + style sheet. + - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSStyleRule, self)._setCssText(cssText) + + # might be (cssText, namespaces) + cssText, namespaces = self._splitNamespacesOff(cssText) + try: + # use parent style sheet ones if available + namespaces = self.parentStyleSheet.namespaces + except AttributeError: + pass + + tokenizer = self._tokenize2(cssText) + selectortokens = self._tokensupto2(tokenizer, blockstartonly=True) + styletokens = self._tokensupto2(tokenizer, blockendonly=True) + trail = self._nexttoken(tokenizer) + if trail: + self._log.error(u'CSSStyleRule: Trailing content: %s' % + self._valuestr(cssText), token=trail) + elif not selectortokens: + self._log.error(u'CSSStyleRule: No selector found: %r' % + self._valuestr(cssText)) + elif self._tokenvalue(selectortokens[0]).startswith(u'@'): + self._log.error(u'CSSStyleRule: No style rule: %r' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + wellformed = True + + bracetoken = selectortokens.pop() + if self._tokenvalue(bracetoken) != u'{': + wellformed = False + self._log.error( + u'CSSStyleRule: No start { of style declaration found: %r' % + self._valuestr(cssText), bracetoken) + elif not selectortokens: + wellformed = False + self._log.error(u'CSSStyleRule: No selector found: %r.' % + self._valuestr(cssText), bracetoken) + newselectorlist = SelectorList(selectorText=(selectortokens, + namespaces), + parentRule=self) + + newstyle = CSSStyleDeclaration() + if not styletokens: + wellformed = False + self._log.error( + u'CSSStyleRule: No style declaration or "}" found: %r' % + self._valuestr(cssText)) + else: + braceorEOFtoken = styletokens.pop() + val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken) + if val != u'}' and typ != 'EOF': + wellformed = False + self._log.error( + u'CSSStyleRule: No "}" after style declaration found: %r' % + self._valuestr(cssText)) + else: + if 'EOF' == typ: + # add again as style needs it + styletokens.append(braceorEOFtoken) + newstyle.cssText = styletokens + + if wellformed: + self._selectorList = newselectorlist + self.style = newstyle + + cssText = property(_getCssText, _setCssText, + doc="(DOM) The parsable textual representation of the rule.") + + + def __getNamespaces(self): + "uses children namespaces if not attached to a sheet, else the sheet's ones" + try: + return self.parentStyleSheet.namespaces + except AttributeError: + return self.selectorList._namespaces + + _namespaces = property(__getNamespaces, doc=u"""if this Rule is + attached to a CSSStyleSheet the namespaces of that sheet are mirrored + here. While the Rule is not attached the namespaces of selectorList + are used.""") + + def _setSelectorList(self, selectorList): + """ + :param selectorList: selectorList, only content is used, not the actual + object + """ + self._checkReadonly() + self.selectorText = selectorList.selectorText + + selectorList = property(lambda self: self._selectorList, _setSelectorList, + doc="The SelectorList of this rule.") + + def _setSelectorText(self, selectorText): + """ + wrapper for cssutils SelectorList object + + :param selectorText: of type string, might also be a comma separated list + of selectors + :Exceptions: + - `NAMESPACE_ERR`: (Selector) + Raised if the specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (SelectorList, Selector) + Raised if the specified CSS string value has a syntax error + and is unparsable. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this rule is readonly. + """ + self._checkReadonly() + self._selectorList.selectorText = selectorText + + selectorText = property(lambda self: self._selectorList.selectorText, + _setSelectorText, + doc="""(DOM) The textual representation of the selector for the + rule set.""") + + def _setStyle(self, style): + """ + :param style: CSSStyleDeclaration or string, only the cssText of a + declaration is used, not the actual object + """ + self._checkReadonly() + if isinstance(style, basestring): + self._style.cssText = style + else: + # cssText would be serialized with optional preferences + # so use _seq! + self._style._seq = style._seq + + style = property(lambda self: self._style, _setStyle, + doc="(DOM) The declaration-block of this rule set.") + + wellformed = property(lambda self: self.selectorList.wellformed) + + def __repr__(self): + if self._namespaces: + st = (self.selectorText, self._namespaces) + else: + st = self.selectorText + return "cssutils.css.%s(selectorText=%r, style=%r)" % ( + self.__class__.__name__, st, self.style.cssText) + + def __str__(self): + return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % ( + self.__class__.__name__, self.selectorText, self.style.cssText, + self._namespaces, id(self)) diff --git a/src/cssutils/css/cssstylesheet.py b/src/cssutils/css/cssstylesheet.py new file mode 100644 index 0000000000..c749086015 --- /dev/null +++ b/src/cssutils/css/cssstylesheet.py @@ -0,0 +1,674 @@ +""" +CSSStyleSheet implements DOM Level 2 CSS CSSStyleSheet. + +Partly also: + - http://dev.w3.org/csswg/cssom/#the-cssstylesheet + - http://www.w3.org/TR/2006/WD-css3-namespace-20060828/ + +TODO: + - ownerRule and ownerNode +""" +__all__ = ['CSSStyleSheet'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssstylesheet.py 1429 2008-08-11 19:01:52Z cthedot $' + +import xml.dom +import cssutils.stylesheets +from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl +from cssutils.helper import Deprecated + +class CSSStyleSheet(cssutils.stylesheets.StyleSheet): + """ + The CSSStyleSheet interface represents a CSS style sheet. + + Properties + ========== + CSSOM + ----- + cssRules + of type CSSRuleList, (DOM readonly) + encoding + reflects the encoding of an @charset rule or 'utf-8' (default) + if set to ``None`` + ownerRule + of type CSSRule, readonly. If this sheet is imported this is a ref + to the @import rule that imports it. + + Inherits properties from stylesheet.StyleSheet + + cssutils + -------- + cssText: string + a textual representation of the stylesheet + namespaces + reflects set @namespace rules of this rule. + A dict of {prefix: namespaceURI} mapping. + + Format + ====== + stylesheet + : [ CHARSET_SYM S* STRING S* ';' ]? + [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* + [ namespace [S|CDO|CDC]* ]* # according to @namespace WD + [ [ ruleset | media | page ] [S|CDO|CDC]* ]* + """ + def __init__(self, href=None, media=None, title=u'', disabled=None, + ownerNode=None, parentStyleSheet=None, readonly=False, + ownerRule=None): + """ + init parameters are the same as for stylesheets.StyleSheet + """ + super(CSSStyleSheet, self).__init__( + 'text/css', href, media, title, disabled, + ownerNode, parentStyleSheet) + + self._ownerRule = ownerRule + self.cssRules = cssutils.css.CSSRuleList() + self.cssRules.append = self.insertRule + self.cssRules.extend = self.insertRule + self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log) + self._readonly = readonly + + # used only during setting cssText by parse*() + self.__encodingOverride = None + self._fetcher = None + + def __iter__(self): + "generator which iterates over cssRules." + for rule in self.cssRules: + yield rule + + def _cleanNamespaces(self): + "removes all namespace rules with same namespaceURI but last one set" + rules = self.cssRules + namespaceitems = self.namespaces.items() + i = 0 + while i < len(rules): + rule = rules[i] + if rule.type == rule.NAMESPACE_RULE and \ + (rule.prefix, rule.namespaceURI) not in namespaceitems: + self.deleteRule(i) + else: + i += 1 + + def _getUsedURIs(self): + "returns set of URIs used in the sheet" + useduris = set() + for r1 in self: + if r1.STYLE_RULE == r1.type: + useduris.update(r1.selectorList._getUsedUris()) + elif r1.MEDIA_RULE == r1.type: + for r2 in r1: + if r2.type == r2.STYLE_RULE: + useduris.update(r2.selectorList._getUsedUris()) + return useduris + + def _getCssText(self): + return cssutils.ser.do_CSSStyleSheet(self) + + def _setCssText(self, cssText): + """ + (cssutils) + Parses ``cssText`` and overwrites the whole stylesheet. + + :param cssText: + a parseable string or a tuple of (cssText, dict-of-namespaces) + :Exceptions: + - `NAMESPACE_ERR`: + If a namespace prefix is found which is not declared. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if the rule is readonly. + - `SYNTAX_ERR`: + Raised if the specified CSS string value has a syntax error and + is unparsable. + """ + self._checkReadonly() + + cssText, namespaces = self._splitNamespacesOff(cssText) + if not namespaces: + namespaces = _SimpleNamespaces(log=self._log) + + tokenizer = self._tokenize2(cssText) + newseq = [] #cssutils.css.CSSRuleList() + + # for closures: must be a mutable + new = {'encoding': None, # needed for setting encoding of @import rules + 'namespaces': namespaces} + def S(expected, seq, token, tokenizer=None): + # @charset must be at absolute beginning of style sheet + if expected == 0: + return 1 + else: + return expected + + def COMMENT(expected, seq, token, tokenizer=None): + "special: sets parent*" + comment = cssutils.css.CSSComment([token], + parentStyleSheet=self.parentStyleSheet) + seq.append(comment) + return expected + + def charsetrule(expected, seq, token, tokenizer): + rule = cssutils.css.CSSCharsetRule(parentStyleSheet=self) + rule.cssText = self._tokensupto2(tokenizer, token) + if expected > 0 or len(seq) > 0: + self._log.error( + u'CSSStylesheet: CSSCharsetRule only allowed at beginning of stylesheet.', + token, xml.dom.HierarchyRequestErr) + else: + if rule.wellformed: + seq.append(rule) + new['encoding'] = rule.encoding + return 1 + + def importrule(expected, seq, token, tokenizer): + if new['encoding']: + # set temporarily as used by _resolveImport + # save newEncoding which have been set by resolveImport + self.__newEncoding = new['encoding'] + + rule = cssutils.css.CSSImportRule(parentStyleSheet=self) + rule.cssText = self._tokensupto2(tokenizer, token) + if expected > 1: + self._log.error( + u'CSSStylesheet: CSSImportRule not allowed here.', + token, xml.dom.HierarchyRequestErr) + else: + if rule.wellformed: + #del rule._parentEncoding # remove as later it is read from this sheet! + seq.append(rule) + + try: + # remove as only used temporarily but may not be set at all + del self.__newEncoding + except AttributeError, e: + pass + + return 1 + + def namespacerule(expected, seq, token, tokenizer): + rule = cssutils.css.CSSNamespaceRule( + cssText=self._tokensupto2(tokenizer, token), + parentStyleSheet=self) + if expected > 2: + self._log.error( + u'CSSStylesheet: CSSNamespaceRule not allowed here.', + token, xml.dom.HierarchyRequestErr) + else: + if rule.wellformed: + seq.append(rule) + # temporary namespaces given to CSSStyleRule and @media + new['namespaces'][rule.prefix] = rule.namespaceURI + return 2 + + def fontfacerule(expected, seq, token, tokenizer): + rule = cssutils.css.CSSFontFaceRule(parentStyleSheet=self) + rule.cssText = self._tokensupto2(tokenizer, token) + if rule.wellformed: + seq.append(rule) + return 3 + + def mediarule(expected, seq, token, tokenizer): + rule = cssutils.css.CSSMediaRule() + rule.cssText = (self._tokensupto2(tokenizer, token), + new['namespaces']) + if rule.wellformed: + rule._parentStyleSheet=self + for r in rule: + r._parentStyleSheet=self + seq.append(rule) + return 3 + + def pagerule(expected, seq, token, tokenizer): + rule = cssutils.css.CSSPageRule(parentStyleSheet=self) + rule.cssText = self._tokensupto2(tokenizer, token) + if rule.wellformed: + seq.append(rule) + return 3 + + def unknownrule(expected, seq, token, tokenizer): + self._log.warn( + u'CSSStylesheet: Unknown @rule found.', + token, neverraise=True) + rule = cssutils.css.CSSUnknownRule(parentStyleSheet=self) + rule.cssText = self._tokensupto2(tokenizer, token) + if rule.wellformed: + seq.append(rule) + return expected + + def ruleset(expected, seq, token, tokenizer): + rule = cssutils.css.CSSStyleRule() + rule.cssText = (self._tokensupto2(tokenizer, token), + new['namespaces']) + if rule.wellformed: + rule._parentStyleSheet=self + seq.append(rule) + return 3 + + # expected: + # ['CHARSET', 'IMPORT', 'NAMESPACE', ('PAGE', 'MEDIA', ruleset)] + wellformed, expected = self._parse(0, newseq, tokenizer, + {'S': S, + 'COMMENT': COMMENT, + 'CDO': lambda *ignored: None, + 'CDC': lambda *ignored: None, + 'CHARSET_SYM': charsetrule, + 'FONT_FACE_SYM': fontfacerule, + 'IMPORT_SYM': importrule, + 'NAMESPACE_SYM': namespacerule, + 'PAGE_SYM': pagerule, + 'MEDIA_SYM': mediarule, + 'ATKEYWORD': unknownrule + }, + default=ruleset) + + if wellformed: + del self.cssRules[:] + for rule in newseq: + self.insertRule(rule, _clean=False) + self._cleanNamespaces() + + cssText = property(_getCssText, _setCssText, + "(cssutils) a textual representation of the stylesheet") + + def _resolveImport(self, url): + """Read (encoding, enctype, decodedContent) from ``url`` for @import + sheets.""" + try: + # only available during parse of a complete sheet + selfAsParentEncoding = self.__newEncoding + except AttributeError: + try: + # explicit @charset + selfAsParentEncoding = self.cssRules[0].encoding + except (IndexError, AttributeError): + # default not UTF-8 but None! + selfAsParentEncoding = None + + return _readUrl(url, fetcher=self._fetcher, + overrideEncoding=self.__encodingOverride, + parentEncoding=selfAsParentEncoding) + + def _setCssTextWithEncodingOverride(self, cssText, encodingOverride=None, + encoding=None): + """Set cssText but use ``encodingOverride`` to overwrite detected + encoding. This is used by parse and @import during setting of cssText. + + If ``encoding`` is given use this but do not save it as encodingOverride""" + if encodingOverride: + # encoding during resolving of @import + self.__encodingOverride = encodingOverride + + self.__newEncoding = encoding # save for nested @import + self.cssText = cssText + + if encodingOverride: + # set encodingOverride explicit again! + self.encoding = self.__encodingOverride + # remove? + self.__encodingOverride = None + elif encoding: + # may e.g. be httpEncoding + self.encoding = encoding + + def _setFetcher(self, fetcher=None): + """sets @import URL loader, if None the default is used""" + self._fetcher = fetcher + + def _setEncoding(self, encoding): + """ + sets encoding of charset rule if present or inserts new charsetrule + with given encoding. If encoding if None removes charsetrule if + present. + """ + try: + rule = self.cssRules[0] + except IndexError: + rule = None + if rule and rule.CHARSET_RULE == rule.type: + if encoding: + rule.encoding = encoding + else: + self.deleteRule(0) + elif encoding: + self.insertRule(cssutils.css.CSSCharsetRule(encoding=encoding), 0) + + def _getEncoding(self): + "return encoding if @charset rule if given or default of 'utf-8'" + try: + return self.cssRules[0].encoding + except (IndexError, AttributeError): + return 'utf-8' + + encoding = property(_getEncoding, _setEncoding, + "(cssutils) reflects the encoding of an @charset rule or 'UTF-8' (default) if set to ``None``") + + namespaces = property(lambda self: self._namespaces, + doc="Namespaces used in this CSSStyleSheet.") + + def add(self, rule): + """ + Adds rule to stylesheet at appropriate position. + Same as ``sheet.insertRule(rule, inOrder=True)``. + """ + return self.insertRule(rule, index=None, inOrder=True) + + def deleteRule(self, index): + """ + Used to delete a rule from the style sheet. + + :param index: + of the rule to remove in the StyleSheet's rule list. For an + index < 0 **no** INDEX_SIZE_ERR is raised but rules for + normal Python lists are used. E.g. ``deleteRule(-1)`` removes + the last rule in cssRules. + :Exceptions: + - `INDEX_SIZE_ERR`: (self) + Raised if the specified index does not correspond to a rule in + the style sheet's rule list. + - `NAMESPACE_ERR`: (self) + Raised if removing this rule would result in an invalid StyleSheet + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this style sheet is readonly. + """ + self._checkReadonly() + + try: + rule = self.cssRules[index] + except IndexError: + raise xml.dom.IndexSizeErr( + u'CSSStyleSheet: %s is not a valid index in the rulelist of length %i' % ( + index, self.cssRules.length)) + else: + if rule.type == rule.NAMESPACE_RULE: + # check all namespacerules if used + uris = [r.namespaceURI for r in self if r.type == r.NAMESPACE_RULE] + useduris = self._getUsedURIs() + if rule.namespaceURI in useduris and\ + uris.count(rule.namespaceURI) == 1: + raise xml.dom.NoModificationAllowedErr( + u'CSSStyleSheet: NamespaceURI defined in this rule is used, cannot remove.') + return + + rule._parentStyleSheet = None # detach + del self.cssRules[index] # delete from StyleSheet + + def insertRule(self, rule, index=None, inOrder=False, _clean=True): + """ + Used to insert a new rule into the style sheet. The new rule now + becomes part of the cascade. + + :Parameters: + rule + a parsable DOMString, in cssutils also a CSSRule or a + CSSRuleList + index + of the rule before the new rule will be inserted. + If the specified index is equal to the length of the + StyleSheet's rule collection, the rule will be added to the end + of the style sheet. + If index is not given or None rule will be appended to rule + list. + inOrder + if True the rule will be put to a proper location while + ignoring index but without raising HIERARCHY_REQUEST_ERR. + The resulting index is returned nevertheless + :returns: the index within the stylesheet's rule collection + :Exceptions: + - `HIERARCHY_REQUEST_ERR`: (self) + Raised if the rule cannot be inserted at the specified index + e.g. if an @import rule is inserted after a standard rule set + or other at-rule. + - `INDEX_SIZE_ERR`: (self) + Raised if the specified index is not a valid insertion point. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this style sheet is readonly. + - `SYNTAX_ERR`: (rule) + Raised if the specified rule has a syntax error and is + unparsable. + """ + self._checkReadonly() + + # check position + if index is None: + index = len(self.cssRules) + elif index < 0 or index > self.cssRules.length: + raise xml.dom.IndexSizeErr( + u'CSSStyleSheet: Invalid index %s for CSSRuleList with a length of %s.' % ( + index, self.cssRules.length)) + return + + if isinstance(rule, basestring): + # init a temp sheet which has the same properties as self + tempsheet = CSSStyleSheet(href=self.href, + media=self.media, + title=self.title, + parentStyleSheet=self.parentStyleSheet, + ownerRule=self.ownerRule) + tempsheet._ownerNode = self.ownerNode + tempsheet._fetcher = self._fetcher + + # prepend encoding if in this sheet to be able to use it in + # @import rules encoding resolution + # do not add if new rule startswith "@charset" (which is exact!) + if not rule.startswith(u'@charset') and (self.cssRules and + self.cssRules[0].type == self.cssRules[0].CHARSET_RULE): + # rule 0 is @charset! + newrulescount, newruleindex = 2, 1 + rule = self.cssRules[0].cssText + rule + else: + newrulescount, newruleindex = 1, 0 + + # parse the new rule(s) + tempsheet.cssText = (rule, self._namespaces) + + if len(tempsheet.cssRules) != newrulescount or (not isinstance( + tempsheet.cssRules[newruleindex], cssutils.css.CSSRule)): + self._log.error(u'CSSStyleSheet: Not a CSSRule: %s' % rule) + return + rule = tempsheet.cssRules[newruleindex] + rule._parentStyleSheet = None # done later? + + # TODO: + #tempsheet._namespaces = self._namespaces + + elif isinstance(rule, cssutils.css.CSSRuleList): + # insert all rules + for i, r in enumerate(rule): + self.insertRule(r, index + i) + return index + + if not rule.wellformed: + self._log.error(u'CSSStyleSheet: Invalid rules cannot be added.') + return + + # CHECK HIERARCHY + # @charset + if rule.type == rule.CHARSET_RULE: + if inOrder: + index = 0 + # always first and only + if (self.cssRules and self.cssRules[0].type == rule.CHARSET_RULE): + self.cssRules[0].encoding = rule.encoding + else: + self.cssRules.insert(0, rule) + elif index != 0 or (self.cssRules and + self.cssRules[0].type == rule.CHARSET_RULE): + self._log.error( + u'CSSStylesheet: @charset only allowed once at the beginning of a stylesheet.', + error=xml.dom.HierarchyRequestErr) + return + else: + self.cssRules.insert(index, rule) + + # @unknown or comment + elif rule.type in (rule.UNKNOWN_RULE, rule.COMMENT) and not inOrder: + if index == 0 and self.cssRules and\ + self.cssRules[0].type == rule.CHARSET_RULE: + self._log.error( + u'CSSStylesheet: @charset must be the first rule.', + error=xml.dom.HierarchyRequestErr) + return + else: + self.cssRules.insert(index, rule) + + # @import + elif rule.type == rule.IMPORT_RULE: + if inOrder: + # automatic order + if rule.type in (r.type for r in self): + # find last of this type + for i, r in enumerate(reversed(self.cssRules)): + if r.type == rule.type: + index = len(self.cssRules) - i + break + else: + # find first point to insert + if self.cssRules and self.cssRules[0].type in (rule.CHARSET_RULE, + rule.COMMENT): + index = 1 + else: + index = 0 + else: + # after @charset + if index == 0 and self.cssRules and\ + self.cssRules[0].type == rule.CHARSET_RULE: + self._log.error( + u'CSSStylesheet: Found @charset at index 0.', + error=xml.dom.HierarchyRequestErr) + return + # before @namespace, @page, @font-face, @media and stylerule + for r in self.cssRules[:index]: + if r.type in (r.NAMESPACE_RULE, r.MEDIA_RULE, r.PAGE_RULE, + r.STYLE_RULE, r.FONT_FACE_RULE): + self._log.error( + u'CSSStylesheet: Cannot insert @import here, found @namespace, @media, @page or CSSStyleRule before index %s.' % + index, + error=xml.dom.HierarchyRequestErr) + return + self.cssRules.insert(index, rule) + + # @namespace + elif rule.type == rule.NAMESPACE_RULE: + if inOrder: + if rule.type in (r.type for r in self): + # find last of this type + for i, r in enumerate(reversed(self.cssRules)): + if r.type == rule.type: + index = len(self.cssRules) - i + break + else: + # find first point to insert + for i, r in enumerate(self.cssRules): + if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE, + r.FONT_FACE_RULE, r.UNKNOWN_RULE, r.COMMENT): + index = i # before these + break + else: + # after @charset and @import + for r in self.cssRules[index:]: + if r.type in (r.CHARSET_RULE, r.IMPORT_RULE): + self._log.error( + u'CSSStylesheet: Cannot insert @namespace here, found @charset or @import after index %s.' % + index, + error=xml.dom.HierarchyRequestErr) + return + # before @media and stylerule + for r in self.cssRules[:index]: + if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE, + r.FONT_FACE_RULE): + self._log.error( + u'CSSStylesheet: Cannot insert @namespace here, found @media, @page or CSSStyleRule before index %s.' % + index, + error=xml.dom.HierarchyRequestErr) + return + + if not (rule.prefix in self.namespaces and + self.namespaces[rule.prefix] == rule.namespaceURI): + # no doublettes + self.cssRules.insert(index, rule) + if _clean: + self._cleanNamespaces() + + # all other where order is not important + else: + if inOrder: + # simply add to end as no specific order + self.cssRules.append(rule) + index = len(self.cssRules) - 1 + else: + for r in self.cssRules[index:]: + if r.type in (r.CHARSET_RULE, r.IMPORT_RULE, r.NAMESPACE_RULE): + self._log.error( + u'CSSStylesheet: Cannot insert rule here, found @charset, @import or @namespace before index %s.' % + index, + error=xml.dom.HierarchyRequestErr) + return + self.cssRules.insert(index, rule) + + # post settings, TODO: for other rules which contain @rules + rule._parentStyleSheet = self + if rule.MEDIA_RULE == rule.type: + for r in rule: + r._parentStyleSheet = self + # ? + elif rule.IMPORT_RULE == rule.type: + rule.href = rule.href # try to reload stylesheet + + return index + + ownerRule = property(lambda self: self._ownerRule, + doc="(DOM attribute) NOT IMPLEMENTED YET") + + @Deprecated('Use cssutils.replaceUrls(sheet, replacer) instead.') + def replaceUrls(self, replacer): + """ + **EXPERIMENTAL** + + Utility method to replace all ``url(urlstring)`` values in + ``CSSImportRules`` and ``CSSStyleDeclaration`` objects (properties). + + ``replacer`` must be a function which is called with a single + argument ``urlstring`` which is the current value of url() + excluding ``url(`` and ``)``. It still may have surrounding + single or double quotes though. + """ + cssutils.replaceUrls(self, replacer) + + def setSerializer(self, cssserializer): + """ + Sets the global Serializer used for output of all stylesheet + output. + """ + if isinstance(cssserializer, cssutils.CSSSerializer): + cssutils.ser = cssserializer + else: + raise ValueError(u'Serializer must be an instance of cssutils.CSSSerializer.') + + def setSerializerPref(self, pref, value): + """ + Sets Preference of CSSSerializer used for output of this + stylesheet. See cssutils.serialize.Preferences for possible + preferences to be set. + """ + cssutils.ser.prefs.__setattr__(pref, value) + + def __repr__(self): + if self.media: + mediaText = self.media.mediaText + else: + mediaText = None + return "cssutils.css.%s(href=%r, media=%r, title=%r)" % ( + self.__class__.__name__, + self.href, mediaText, self.title) + + def __str__(self): + if self.media: + mediaText = self.media.mediaText + else: + mediaText = None + return "<cssutils.css.%s object encoding=%r href=%r "\ + "media=%r title=%r namespaces=%r at 0x%x>" % ( + self.__class__.__name__, self.encoding, self.href, + mediaText, self.title, self.namespaces.namespaces, + id(self)) diff --git a/src/cssutils/css/cssunknownrule.py b/src/cssutils/css/cssunknownrule.py new file mode 100644 index 0000000000..4396932ae1 --- /dev/null +++ b/src/cssutils/css/cssunknownrule.py @@ -0,0 +1,208 @@ +"""CSSUnknownRule implements DOM Level 2 CSS CSSUnknownRule. +""" +__all__ = ['CSSUnknownRule'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssunknownrule.py 1170 2008-03-20 17:42:07Z cthedot $' + +import xml.dom +import cssrule +import cssutils + +class CSSUnknownRule(cssrule.CSSRule): + """ + represents an at-rule not supported by this user agent. + + Properties + ========== + inherited from CSSRule + - cssText + - type + + cssutils only + ------------- + atkeyword + the literal keyword used + seq + All parts of this rule excluding @KEYWORD but including CSSComments + wellformed + if this Rule is wellformed, for Unknown rules if an atkeyword is set + at all + + Format + ====== + unknownrule: + @xxx until ';' or block {...} + """ + type = property(lambda self: cssrule.CSSRule.UNKNOWN_RULE) + + def __init__(self, cssText=u'', parentRule=None, + parentStyleSheet=None, readonly=False): + """ + cssText + of type string + """ + super(CSSUnknownRule, self).__init__(parentRule=parentRule, + parentStyleSheet=parentStyleSheet) + self._atkeyword = None + if cssText: + self.cssText = cssText + + self._readonly = readonly + + def _getCssText(self): + """ returns serialized property cssText """ + return cssutils.ser.do_CSSUnknownRule(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - SYNTAX_ERR: + Raised if the specified CSS string value has a syntax error and + is unparsable. + - INVALID_MODIFICATION_ERR: + Raised if the specified CSS string value represents a different + type of rule than the current one. + - HIERARCHY_REQUEST_ERR: (never raised) + Raised if the rule cannot be inserted at this point in the + style sheet. + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + """ + super(CSSUnknownRule, self)._setCssText(cssText) + tokenizer = self._tokenize2(cssText) + attoken = self._nexttoken(tokenizer, None) + if not attoken or self._type(attoken) != self._prods.ATKEYWORD: + self._log.error(u'CSSUnknownRule: No CSSUnknownRule found: %s' % + self._valuestr(cssText), + error=xml.dom.InvalidModificationErr) + else: + # for closures: must be a mutable + new = {'nesting': [], # {} [] or () + 'wellformed': True + } + + def CHAR(expected, seq, token, tokenizer=None): + type_, val, line, col = token + if expected != 'EOF': + if val in u'{[(': + new['nesting'].append(val) + elif val in u'}])': + opening = {u'}': u'{', u']': u'[', u')': u'('}[val] + try: + if new['nesting'][-1] == opening: + new['nesting'].pop() + else: + raise IndexError() + except IndexError: + new['wellformed'] = False + self._log.error(u'CSSUnknownRule: Wrong nesting of {, [ or (.', + token=token) + + if val in u'};' and not new['nesting']: + expected = 'EOF' + + seq.append(val, type_, line=line, col=col) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSUnknownRule: Expected end of rule.', + token=token) + return expected + + def EOF(expected, seq, token, tokenizer=None): + "close all blocks and return 'EOF'" + for x in reversed(new['nesting']): + closing = {u'{': u'}', u'[': u']', u'(': u')'}[x] + seq.append(closing, closing) + new['nesting'] = [] + return 'EOF' + + def INVALID(expected, seq, token, tokenizer=None): + # makes rule invalid + self._log.error(u'CSSUnknownRule: Bad syntax.', + token=token, error=xml.dom.SyntaxErr) + new['wellformed'] = False + return expected + + def STRING(expected, seq, token, tokenizer=None): + type_, val, line, col = token + val = self._stringtokenvalue(token) + if expected != 'EOF': + seq.append(val, type_, line=line, col=col) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSUnknownRule: Expected end of rule.', + token=token) + return expected + + def URI(expected, seq, token, tokenizer=None): + type_, val, line, col = token + val = self._uritokenvalue(token) + if expected != 'EOF': + seq.append(val, type_, line=line, col=col) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSUnknownRule: Expected end of rule.', + token=token) + return expected + + def default(expected, seq, token, tokenizer=None): + type_, val, line, col = token + if expected != 'EOF': + seq.append(val, type_, line=line, col=col) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSUnknownRule: Expected end of rule.', + token=token) + return expected + + # unknown : ATKEYWORD S* ... ; | } + newseq = self._tempSeq() + wellformed, expected = self._parse(expected=None, + seq=newseq, tokenizer=tokenizer, + productions={'CHAR': CHAR, + 'EOF': EOF, + 'INVALID': INVALID, + 'STRING': STRING, + 'URI': URI, + 'S': default # overwrite default default! + }, + default=default, + new=new) + + # wellformed set by parse + wellformed = wellformed and new['wellformed'] + + # post conditions + if expected != 'EOF': + wellformed = False + self._log.error( + u'CSSUnknownRule: No ending ";" or "}" found: %r' % + self._valuestr(cssText)) + elif new['nesting']: + wellformed = False + self._log.error( + u'CSSUnknownRule: Unclosed "{", "[" or "(": %r' % + self._valuestr(cssText)) + + # set all + if wellformed: + self.atkeyword = self._tokenvalue(attoken) + self._setSeq(newseq) + + cssText = property(fget=_getCssText, fset=_setCssText, + doc="(DOM) The parsable textual representation.") + + wellformed = property(lambda self: bool(self.atkeyword)) + + def __repr__(self): + return "cssutils.css.%s(cssText=%r)" % ( + self.__class__.__name__, self.cssText) + + def __str__(self): + return "<cssutils.css.%s object cssText=%r at 0x%x>" % ( + self.__class__.__name__, self.cssText, id(self)) diff --git a/src/cssutils/css/cssvalue.py b/src/cssutils/css/cssvalue.py new file mode 100644 index 0000000000..ddf38a4747 --- /dev/null +++ b/src/cssutils/css/cssvalue.py @@ -0,0 +1,1379 @@ +"""CSSValue related classes + +- CSSValue implements DOM Level 2 CSS CSSValue +- CSSPrimitiveValue implements DOM Level 2 CSS CSSPrimitiveValue +- CSSValueList implements DOM Level 2 CSS CSSValueList + +""" +__all__ = ['CSSValue', 'CSSPrimitiveValue', 'CSSValueList', 'CSSColor'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssvalue.py 1473 2008-09-15 21:15:54Z cthedot $' + +import re +import xml.dom +import cssutils +from cssutils.profiles import profiles +from cssutils.prodparser import * + + +class CSSValue(cssutils.util.Base2): + """ + The CSSValue interface represents a simple or a complex value. + A CSSValue object only occurs in a context of a CSS property + + Properties + ========== + cssText + A string representation of the current value. + cssValueType + A (readonly) code defining the type of the value. + + seq: a list (cssutils) + All parts of this style declaration including CSSComments + valid: boolean + if the value is valid at all, False for e.g. color: #1 + wellformed + if this Property is syntactically ok + + _value (INTERNAL!) + value without any comments, used to validate + """ + + CSS_INHERIT = 0 + """ + The value is inherited and the cssText contains "inherit". + """ + CSS_PRIMITIVE_VALUE = 1 + """ + The value is a primitive value and an instance of the + CSSPrimitiveValue interface can be obtained by using binding-specific + casting methods on this instance of the CSSValue interface. + """ + CSS_VALUE_LIST = 2 + """ + The value is a CSSValue list and an instance of the CSSValueList + interface can be obtained by using binding-specific casting + methods on this instance of the CSSValue interface. + """ + CSS_CUSTOM = 3 + """ + The value is a custom value. + """ + _typestrings = ['CSS_INHERIT' , 'CSS_PRIMITIVE_VALUE', 'CSS_VALUE_LIST', + 'CSS_CUSTOM'] + + def __init__(self, cssText=None, readonly=False, _propertyName=None): + """ + inits a new CSS Value + + cssText + the parsable cssText of the value + readonly + defaults to False + property + used to validate this value in the context of a property + """ + super(CSSValue, self).__init__() + + #self.seq = [] + self.valid = False + self.wellformed = False + self._valueValue = u'' + self._linetoken = None # used for line report only + self._propertyName = _propertyName + + if cssText is not None: # may be 0 + if type(cssText) in (int, float): + cssText = unicode(cssText) # if it is a number + self.cssText = cssText + + self._readonly = readonly + + def _getValue(self): + # TODO: + v = [] + for item in self.seq: + type_, val = item.type, item.value + if isinstance(val, cssutils.css.CSSComment): + # only value here + continue + elif 'STRING' == type_: + v.append(cssutils.ser._string(val)) + elif 'URI' == type_: + v.append(cssutils.ser._uri(val)) + elif u',' == val: + # list of items + v.append(u' ') + v.append(val) + elif isinstance(val, basestring): + v.append(val) + else: + # maybe CSSPrimitiveValue + v.append(val.cssText) + if v and u'' == v[-1].strip(): + # simple strip of joined string does not work for escaped spaces + del v[-1] + return u''.join(v) + + def _setValue(self, value): + "overwritten by CSSValueList!" + self._valueValue = value + + _value = property(_getValue, _setValue, + doc="Actual cssText value of this CSSValue.") + + def _getCssText(self): + return cssutils.ser.do_css_CSSValue(self) + + def _setCssText(self, cssText): + """ + Format + ====== + :: + + unary_operator + : '-' | '+' + ; + operator + : '/' S* | ',' S* | /* empty */ + ; + expr + : term [ operator term ]* + ; + term + : unary_operator? + [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | + TIME S* | FREQ S* ] + | STRING S* | IDENT S* | URI S* | hexcolor | function + ; + function + : FUNCTION S* expr ')' S* + ; + /* + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + */ + hexcolor + : HASH S* + ; + + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error + (according to the attached property) or is unparsable. + - TODO: INVALID_MODIFICATION_ERR: + Raised if the specified CSS string value represents a different + type of values than the values allowed by the CSS property. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this value is readonly. + """ + self._checkReadonly() + + # for closures: must be a mutable + new = {'rawvalues': [], # used for validation + 'values': [], + 'commas': 0, + 'valid': True, + 'wellformed': True } + + def _S(expected, seq, token, tokenizer=None): + type_, val, line, col = token + new['rawvalues'].append(u' ') + if expected == 'operator': #expected.endswith('operator'): + seq.append(u' ', 'separator', line=line, col=col) + return 'term or operator' + elif expected.endswith('S'): + return 'term or S' + else: + return expected + + def _char(expected, seq, token, tokenizer=None): + type_, val, line, col = token + new['rawvalues'].append(val) + + if 'funcend' == expected and u')' == val: + # end of FUNCTION + seq.appendToVal(val) + new['values'].append(seq[-1]) + return 'operator' + + elif expected in (')', ']', '}') and expected == val: + # end of any block: (), [], {} + seq.appendToVal(val) + return 'operator' + + elif expected in ('funcend', ')', ']', '}'): + # content of func or block: (), [], {} + seq.appendToVal(val) + return expected + + elif expected.endswith('operator') and ',' == val: + # term, term; remove all WS between terms!!! + new['commas'] += 1 + if seq and seq[-1].type == 'separator': + seq.replace(-1, val, type_, line=line, col=col) + else: + seq.append(val, type_, line=line, col=col) + return 'term or S' + + elif expected.endswith('operator') and '/' == val: + # term / term + if seq and seq[-1].value == u' ': + old = seq[-1] + seq.replace(-1, val, old.type, old.line, old.col) + #seq[-1] = val + else: + seq.append(val, type_, line=line, col=col) + return 'term or S' + + elif expected.startswith('term') and u'(' == val: + # start of ( any* ) block + seq.append(val, type_, line=line, col=col) + return ')' + elif expected.startswith('term') and u'[' == val: + # start of [ any* ] block + seq.append(val, type_, line=line, col=col) + return ']' + elif expected.startswith('term') and u'{' == val: + # start of { any* } block + seq.append(val, type_, line=line, col=col) + return '}' + elif expected.startswith('term') and u'+' == val: + # unary operator "+" + seq.append(val, type_, line=line, col=col) + new['values'].append(val) + return 'number percentage dimension' + elif expected.startswith('term') and u'-' == val: + # unary "-" operator + seq.append(val, type_, line=line, col=col) + new['values'].append(val) + return 'number percentage dimension' + elif expected.startswith('term') and u'/' == val: + # font-size/line-height separator + seq.append(val, type_, line=line, col=col) + new['values'].append(val) + return 'number percentage dimension' + else: + new['wellformed'] = False + self._log.error(u'CSSValue: Unexpected char.', token) + return expected + + def _number_percentage_dimension(expected, seq, token, tokenizer=None): + # NUMBER PERCENTAGE DIMENSION after -/+ or operator + type_, val, line, col = token + new['rawvalues'].append(val) + if expected.startswith('term') or expected == 'number percentage dimension': + # normal value + if new['values'] and new['values'][-1] in (u'-', u'+'): + new['values'][-1] += val + else: + new['values'].append(val) + seq.append(val, type_, line=line, col=col) + return 'operator' + elif 'operator' == expected: + # expected S but token which is ok + if new['values'] and new['values'][-1] in (u'-', u'+'): + new['values'][-1] += val + else: + new['values'].append(u' ') + seq.append(u' ', 'separator') # self._prods.S + new['values'].append(val) + seq.append(val, type_, line=line, col=col) + return 'operator' + elif expected in ('funcend', ')', ']', '}'): + # a block + seq.appendToVal(val) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSValue: Unexpected token.', token) + return expected + + def _string_ident_uri(expected, seq, token, tokenizer=None): + # STRING IDENT URI + type_, val, line, col = token + + new['rawvalues'].append(val) + if expected.startswith('term'): + # normal value + if self._prods.STRING == type_: + val = self._stringtokenvalue(token) + elif self._prods.URI == type_: + val = self._uritokenvalue(token) + new['values'].append(val) + seq.append(val, type_, line=line, col=col) + return 'operator' + elif 'operator' == expected: + # expected S but still ok + if self._prods.STRING == type_: + val = self._stringtokenvalue(token) + elif self._prods.URI == type_: + val = self._uritokenvalue(token) + new['values'].append(u' ') + new['values'].append(val) + seq.append(u' ', 'separator') # self._prods.S + seq.append(val, type_, line=line, col=col) + return 'operator' + elif expected in ('funcend', ')', ']', '}'): + # a block + seq.appendToVal(val) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSValue: Unexpected token.', token) + return expected + + def _hash(expected, seq, token, tokenizer=None): + # HASH + type_, val, line, col = token + new['rawvalues'].append(val) + + val = CSSColor(cssText=token) + type_ = type(val) + if expected.startswith('term'): + # normal value + new['values'].append(val) + seq.append(val, type_, line=line, col=col) + return 'operator' + elif 'operator' == expected: + # expected S but still ok + new['values'].append(u' ') + new['values'].append(val) + seq.append(u' ', 'separator') # self._prods.S + seq.append(val, type_, line=line, col=col) + return 'operator' + elif expected in ('funcend', ')', ']', '}'): + # a block + seq.appendToVal(val) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSValue: Unexpected token.', token) + return expected + + def _function(expected, seq, token, tokenizer=None): + # FUNCTION incl colors + type_, val, line, col = token + + if self._normalize(val) in ('rgb(', 'rgba(', 'hsl(', 'hsla('): + # a CSSColor + val = CSSColor(cssText=(token, tokenizer)) + type_ = type(val) + seq.append(val, type_, line=line, col=col) + new['values'].append(val) + new['rawvalues'].append(val.cssText) + return 'operator' + + new['rawvalues'].append(val) + + if expected.startswith('term'): + # normal value but add if funcend is found + seq.append(val, type_, line=line, col=col) + return 'funcend' + elif 'operator' == expected: + # normal value but add if funcend is found + seq.append(u' ', 'separator') # self._prods.S + seq.append(val, type_, line=line, col=col) + return 'funcend' + elif expected in ('funcend', ')', ']', '}'): + # a block + seq.appendToVal(val) + return expected + else: + new['wellformed'] = False + self._log.error(u'CSSValue: Unexpected token.', token) + return expected + + tokenizer = self._tokenize2(cssText) + + linetoken = self._nexttoken(tokenizer) + if not linetoken: + self._log.error(u'CSSValue: Unknown syntax or no value: %r.' % + self._valuestr(cssText)) + else: + newseq = self._tempSeq() # [] + wellformed, expected = self._parse(expected='term', + seq=newseq, tokenizer=tokenizer,initialtoken=linetoken, + productions={'S': _S, + 'CHAR': _char, + + 'NUMBER': _number_percentage_dimension, + 'PERCENTAGE': _number_percentage_dimension, + 'DIMENSION': _number_percentage_dimension, + + 'STRING': _string_ident_uri, + 'IDENT': _string_ident_uri, + 'URI': _string_ident_uri, + 'HASH': _hash, + 'UNICODE-RANGE': _string_ident_uri, #? + + 'FUNCTION': _function + }) + + wellformed = wellformed and new['wellformed'] + + # post conditions + def lastseqvalue(seq): + """find last actual value in seq, not COMMENT!""" + for i, item in enumerate(reversed(seq)): + if 'COMMENT' != item.type: + return len(seq)-1-i, item.value + else: + return 0, None + lastpos, lastval = lastseqvalue(newseq) + + if expected.startswith('term') and lastval != u' ' or ( + expected in ('funcend', ')', ']', '}')): + wellformed = False + self._log.error(u'CSSValue: Incomplete value: %r.' % + self._valuestr(cssText)) + + if not new['values']: + wellformed = False + self._log.error(u'CSSValue: Unknown syntax or no value: %r.' % + self._valuestr(cssText)) + + else: + # remove last token if 'separator' + if lastval == u' ': + del newseq[lastpos] + + self._linetoken = linetoken # used for line report + self._setSeq(newseq) + + self.valid = self._validate(u''.join(new['rawvalues'])) + + if len(new['values']) == 1 and new['values'][0] == u'inherit': + self._value = u'inherit' + self._cssValueType = CSSValue.CSS_INHERIT + self.__class__ = CSSValue # reset + elif len(new['values']) == 1: + self.__class__ = CSSPrimitiveValue + self._init() #inits CSSPrimitiveValue + elif len(new['values']) > 1 and\ + len(new['values']) == new['commas'] + 1: + # e.g. value for font-family: a, b + self.__class__ = CSSPrimitiveValue + self._init() #inits CSSPrimitiveValue + elif len(new['values']) > 1: + # separated by S + self.__class__ = CSSValueList + self._init() # inits CSSValueList + else: + self._cssValueType = CSSValue.CSS_CUSTOM + self.__class__ = CSSValue # reset + + self.wellformed = wellformed + + cssText = property(_getCssText, _setCssText, + doc="A string representation of the current value.") + + def _getCssValueType(self): + if hasattr(self, '_cssValueType'): + return self._cssValueType + + cssValueType = property(_getCssValueType, + doc="A (readonly) code defining the type of the value as defined above.") + + def _getCssValueTypeString(self): + t = self.cssValueType + if t is not None: # may be 0! + return CSSValue._typestrings[t] + else: + return None + + cssValueTypeString = property(_getCssValueTypeString, + doc="cssutils: Name of cssValueType of this CSSValue (readonly).") + + def _validate(self, value=None, profile=None): + """ + validates value against _propertyName context if given + """ + valid = False + if self._value: + if self._propertyName and self._propertyName in profiles.propertiesByProfile(): + valid, validprofile = \ + profiles.validateWithProfile(self._propertyName, + self._normalize(self._value)) + if not validprofile: + validprofile = u'' + + if not valid: + self._log.warn( + u'CSSValue: Invalid value for %s property "%s: %s".' % + (validprofile, self._propertyName, + self._value), neverraise=True) + elif profile and validprofile != profile: + self._log.warn( + u'CSSValue: Invalid value for %s property "%s: %s" but valid %s property.' % + (profile, self._propertyName, self._value, + validprofile), neverraise=True) + else: + self._log.debug( + u'CSSValue: Found valid %s property "%s: %s".' % + (validprofile, self._propertyName, self._value), + neverraise=True) + else: + self._log.debug(u'CSSValue: Unable to validate as no or unknown property context set for value: %r' + % self._value, neverraise=True) + + if not value: + # if value is given this should not be saved + self.valid = valid + return valid + + def _get_propertyName(self): + return self.__propertyName + + def _set_propertyName(self, _propertyName): + self.__propertyName = _propertyName + self._validate() + + _propertyName = property(_get_propertyName, _set_propertyName, + doc="cssutils: Property this values is validated against") + + def __repr__(self): + return "cssutils.css.%s(%r, _propertyName=%r)" % ( + self.__class__.__name__, self.cssText, self._propertyName) + + def __str__(self): + return "<cssutils.css.%s object cssValueType=%r cssText=%r propname=%r valid=%r at 0x%x>" % ( + self.__class__.__name__, self.cssValueTypeString, + self.cssText, self._propertyName, self.valid, id(self)) + + +class CSSPrimitiveValue(CSSValue): + """ + represents a single CSS Value. May be used to determine the value of a + specific style property currently set in a block or to set a specific + style property explicitly within the block. Might be obtained from the + getPropertyCSSValue method of CSSStyleDeclaration. + + Conversions are allowed between absolute values (from millimeters to + centimeters, from degrees to radians, and so on) but not between + relative values. (For example, a pixel value cannot be converted to a + centimeter value.) Percentage values can't be converted since they are + relative to the parent value (or another property value). There is one + exception for color percentage values: since a color percentage value + is relative to the range 0-255, a color percentage value can be + converted to a number; (see also the RGBColor interface). + """ + # constant: type of this CSSValue class + cssValueType = CSSValue.CSS_PRIMITIVE_VALUE + + # An integer indicating which type of unit applies to the value. + CSS_UNKNOWN = 0 # only obtainable via cssText + CSS_NUMBER = 1 + CSS_PERCENTAGE = 2 + CSS_EMS = 3 + CSS_EXS = 4 + CSS_PX = 5 + CSS_CM = 6 + CSS_MM = 7 + CSS_IN = 8 + CSS_PT = 9 + CSS_PC = 10 + CSS_DEG = 11 + CSS_RAD = 12 + CSS_GRAD = 13 + CSS_MS = 14 + CSS_S = 15 + CSS_HZ = 16 + CSS_KHZ = 17 + CSS_DIMENSION = 18 + CSS_STRING = 19 + CSS_URI = 20 + CSS_IDENT = 21 + CSS_ATTR = 22 + CSS_COUNTER = 23 + CSS_RECT = 24 + CSS_RGBCOLOR = 25 + # NOT OFFICIAL: + CSS_RGBACOLOR = 26 + + _floattypes = [CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS, + CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC, + CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS, CSS_S, + CSS_HZ, CSS_KHZ, CSS_DIMENSION + ] + _stringtypes = [CSS_ATTR, CSS_IDENT, CSS_STRING, CSS_URI] + _countertypes = [CSS_COUNTER] + _recttypes = [CSS_RECT] + _rbgtypes = [CSS_RGBCOLOR, CSS_RGBACOLOR] + + _reNumDim = re.compile(ur'^(.*?)([a-z]+|%)$', re.I| re.U|re.X) + + # oldtype: newType: converterfunc + _converter = { + # cm <-> mm <-> in, 1 inch is equal to 2.54 centimeters. + # pt <-> pc, the points used by CSS 2.1 are equal to 1/72nd of an inch. + # pc: picas - 1 pica is equal to 12 points + (CSS_CM, CSS_MM): lambda x: x * 10, + (CSS_MM, CSS_CM): lambda x: x / 10, + + (CSS_PT, CSS_PC): lambda x: x * 12, + (CSS_PC, CSS_PT): lambda x: x / 12, + + (CSS_CM, CSS_IN): lambda x: x / 2.54, + (CSS_IN, CSS_CM): lambda x: x * 2.54, + (CSS_MM, CSS_IN): lambda x: x / 25.4, + (CSS_IN, CSS_MM): lambda x: x * 25.4, + + (CSS_IN, CSS_PT): lambda x: x / 72, + (CSS_PT, CSS_IN): lambda x: x * 72, + (CSS_CM, CSS_PT): lambda x: x / 2.54 / 72, + (CSS_PT, CSS_CM): lambda x: x * 72 * 2.54, + (CSS_MM, CSS_PT): lambda x: x / 25.4 / 72, + (CSS_PT, CSS_MM): lambda x: x * 72 * 25.4, + + (CSS_IN, CSS_PC): lambda x: x / 72 / 12, + (CSS_PC, CSS_IN): lambda x: x * 12 * 72, + (CSS_CM, CSS_PC): lambda x: x / 2.54 / 72 / 12, + (CSS_PC, CSS_CM): lambda x: x * 12 * 72 * 2.54, + (CSS_MM, CSS_PC): lambda x: x / 25.4 / 72 / 12, + (CSS_PC, CSS_MM): lambda x: x * 12 * 72 * 25.4, + + # hz <-> khz + (CSS_KHZ, CSS_HZ): lambda x: x * 1000, + (CSS_HZ, CSS_KHZ): lambda x: x / 1000, + # s <-> ms + (CSS_S, CSS_MS): lambda x: x * 1000, + (CSS_MS, CSS_S): lambda x: x / 1000 + + # TODO: convert deg <-> rad <-> grad + } + + def __init__(self, cssText=None, readonly=False, _propertyName=None): + """ + see CSSPrimitiveValue.__init__() + """ + super(CSSPrimitiveValue, self).__init__(cssText=cssText, + readonly=readonly, + _propertyName=_propertyName) + + #(String representation for unit types, token type of unit type, detail) + # used to detect primitiveType and for __repr__ + self._init() + + def _init(self): + # _unitinfos must be set here as self._prods is not known before + self._unitinfos = [ + ('CSS_UNKNOWN', None, None), + ('CSS_NUMBER', self._prods.NUMBER, None), + ('CSS_PERCENTAGE', self._prods.PERCENTAGE, None), + ('CSS_EMS', self._prods.DIMENSION, 'em'), + ('CSS_EXS', self._prods.DIMENSION, 'ex'), + ('CSS_PX', self._prods.DIMENSION, 'px'), + ('CSS_CM', self._prods.DIMENSION, 'cm'), + ('CSS_MM', self._prods.DIMENSION, 'mm'), + ('CSS_IN', self._prods.DIMENSION, 'in'), + ('CSS_PT', self._prods.DIMENSION, 'pt'), + ('CSS_PC', self._prods.DIMENSION, 'pc'), + ('CSS_DEG', self._prods.DIMENSION, 'deg'), + ('CSS_RAD', self._prods.DIMENSION, 'rad'), + ('CSS_GRAD', self._prods.DIMENSION, 'grad'), + ('CSS_MS', self._prods.DIMENSION, 'ms'), + ('CSS_S', self._prods.DIMENSION, 's'), + ('CSS_HZ', self._prods.DIMENSION, 'hz'), + ('CSS_KHZ', self._prods.DIMENSION, 'khz'), + ('CSS_DIMENSION', self._prods.DIMENSION, None), + ('CSS_STRING', self._prods.STRING, None), + ('CSS_URI', self._prods.URI, None), + ('CSS_IDENT', self._prods.IDENT, None), + ('CSS_ATTR', self._prods.FUNCTION, 'attr('), + ('CSS_COUNTER', self._prods.FUNCTION, 'counter('), + ('CSS_RECT', self._prods.FUNCTION, 'rect('), + ('CSS_RGBCOLOR', self._prods.FUNCTION, 'rgb('), + ('CSS_RGBACOLOR', self._prods.FUNCTION, 'rgba('), + ] + + def __set_primitiveType(self): + """ + primitiveType is readonly but is set lazy if accessed + no value is given as self._value is used + """ + primitiveType = self.CSS_UNKNOWN + + for item in self.seq: + if item.type == self._prods.URI: + primitiveType = self.CSS_URI + break + elif item.type == self._prods.STRING: + primitiveType = self.CSS_STRING + break + else: + + _floatType = False # if unary expect NUMBER DIMENSION or PERCENTAGE + tokenizer = self._tokenize2(self._value) + t = self._nexttoken(tokenizer) + if not t: + self._log.error(u'CSSPrimitiveValue: No value.') + + # unary operator: + if self._tokenvalue(t) in (u'-', u'+'): + t = self._nexttoken(tokenizer) + if not t: + self._log.error(u'CSSPrimitiveValue: No value.') + + _floatType = True + + # check for font1, "font2" etc which is treated as ONE string + fontstring = 0 # should be at leayst 2 + expected = 'ident or string' + tokenizer = self._tokenize2(self._value) # add used tokens again + for token in tokenizer: + val, typ = self._tokenvalue(token, normalize=True), self._type(token) + if expected == 'ident or string' and typ in ( + self._prods.IDENT, self._prods.STRING): + expected = 'comma' + fontstring += 1 + elif expected == 'comma' and val == ',': + expected = 'ident or string' + fontstring += 1 + elif typ in ('separator', self._prods.S, self._prods.COMMENT): + continue + else: + fontstring = False + break + + if fontstring > 2: + # special case: e.g. for font-family: a, b; only COMMA IDENT and STRING + primitiveType = CSSPrimitiveValue.CSS_STRING + elif self._type(t) == self._prods.HASH: + # special case, maybe should be converted to rgb in any case? + primitiveType = CSSPrimitiveValue.CSS_RGBCOLOR + else: + for i, (name, tokentype, search) in enumerate(self._unitinfos): + val, typ = self._tokenvalue(t, normalize=True), self._type(t) + if typ == tokentype: + if typ == self._prods.DIMENSION: + if not search: + primitiveType = i + break + elif re.match(ur'^[^a-z]*(%s)$' % search, val): + primitiveType = i + break + elif typ == self._prods.FUNCTION: + if not search: + primitiveType = i + break + elif val.startswith(search): + primitiveType = i + break + else: + primitiveType = i + break + + if _floatType and primitiveType not in self._floattypes: + # - or + only expected before floattype + primitiveType = self.CSS_UNKNOWN + + self._primitiveType = primitiveType + + def _getPrimitiveType(self): + if not hasattr(self, '_primitivetype'): + self.__set_primitiveType() + return self._primitiveType + + primitiveType = property(_getPrimitiveType, + doc="READONLY: The type of the value as defined by the constants specified above.") + + def _getPrimitiveTypeString(self): + return self._unitinfos[self.primitiveType][0] + + primitiveTypeString = property(_getPrimitiveTypeString, + doc="Name of primitive type of this value.") + + def _getCSSPrimitiveTypeString(self, type): + "get TypeString by given type which may be unknown, used by setters" + try: + return self._unitinfos[type][0] + except (IndexError, TypeError): + return u'%r (UNKNOWN TYPE)' % type + + def __getValDim(self): + "splits self._value in numerical and dimension part" + try: + val, dim = self._reNumDim.findall(self._value)[0] + except IndexError: + val, dim = self._value, u'' + try: + val = float(val) + except ValueError: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: No float value %r' + % (self._value)) + + return val, dim + + def getFloatValue(self, unitType=None): + """ + (DOM method) This method is used to get a float value in a + specified unit. If this CSS value doesn't contain a float value + or can't be converted into the specified unit, a DOMException + is raised. + + unitType + to get the float value. The unit code can only be a float unit type + (i.e. CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS, CSS_PX, CSS_CM, + CSS_MM, CSS_IN, CSS_PT, CSS_PC, CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS, + CSS_S, CSS_HZ, CSS_KHZ, CSS_DIMENSION) or None in which case + the current dimension is used. + + returns not necessarily a float but some cases just an integer + e.g. if the value is ``1px`` it return ``1`` and **not** ``1.0`` + + conversions might return strange values like 1.000000000001 + """ + if unitType is not None and unitType not in self._floattypes: + raise xml.dom.InvalidAccessErr( + u'unitType Parameter is not a float type') + + val, dim = self.__getValDim() + + if unitType is not None and self.primitiveType != unitType: + # convert if needed + try: + val = self._converter[self.primitiveType, unitType](val) + except KeyError: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r' + % (self.primitiveTypeString, + self._getCSSPrimitiveTypeString(unitType))) + + if val == int(val): + val = int(val) + + return val + + def setFloatValue(self, unitType, floatValue): + """ + (DOM method) A method to set the float value with a specified unit. + If the property attached with this value can not accept the + specified unit or the float value, the value will be unchanged and + a DOMException will be raised. + + unitType + a unit code as defined above. The unit code can only be a float + unit type + floatValue + the new float value which does not have to be a float value but + may simple be an int e.g. if setting:: + + setFloatValue(CSS_PX, 1) + + raises DOMException + - INVALID_ACCESS_ERR: Raised if the attached property doesn't + support the float value or the unit type. + - NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + """ + self._checkReadonly() + if unitType not in self._floattypes: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: unitType %r is not a float type' % + self._getCSSPrimitiveTypeString(unitType)) + try: + val = float(floatValue) + except ValueError, e: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: floatValue %r is not a float' % + floatValue) + + oldval, dim = self.__getValDim() + + if self.primitiveType != unitType: + # convert if possible + try: + val = self._converter[ + unitType, self.primitiveType](val) + except KeyError: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r' + % (self.primitiveTypeString, + self._getCSSPrimitiveTypeString(unitType))) + + if val == int(val): + val = int(val) + + self.cssText = '%s%s' % (val, dim) + + def getStringValue(self): + """ + (DOM method) This method is used to get the string value. If the + CSS value doesn't contain a string value, a DOMException is raised. + + Some properties (like 'font-family' or 'voice-family') + convert a whitespace separated list of idents to a string. + + Only the actual value is returned so e.g. all the following return the + actual value ``a``: url(a), attr(a), "a", 'a' + """ + if self.primitiveType not in self._stringtypes: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue %r is not a string type' + % self.primitiveTypeString) + + if CSSPrimitiveValue.CSS_STRING == self.primitiveType: + # _stringtokenvalue expects tuple with at least 2 + return self._stringtokenvalue((None,self._value)) + elif CSSPrimitiveValue.CSS_URI == self.primitiveType: + # _uritokenvalue expects tuple with at least 2 + return self._uritokenvalue((None, self._value)) + elif CSSPrimitiveValue.CSS_ATTR == self.primitiveType: + return self._value[5:-1] + else: + return self._value + + def setStringValue(self, stringType, stringValue): + """ + (DOM method) A method to set the string value with the specified + unit. If the property attached to this value can't accept the + specified unit or the string value, the value will be unchanged and + a DOMException will be raised. + + stringType + a string code as defined above. The string code can only be a + string unit type (i.e. CSS_STRING, CSS_URI, CSS_IDENT, and + CSS_ATTR). + stringValue + the new string value + Only the actual value is expected so for (CSS_URI, "a") the + new value will be ``url(a)``. For (CSS_STRING, "'a'") + the new value will be ``"\\'a\\'"`` as the surrounding ``'`` are + not part of the string value + + raises + DOMException + + - INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a + string value or if the string value can't be converted into + the specified unit. + + - NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + """ + self._checkReadonly() + # self not stringType + if self.primitiveType not in self._stringtypes: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue %r is not a string type' + % self.primitiveTypeString) + # given stringType is no StringType + if stringType not in self._stringtypes: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: stringType %s is not a string type' + % self._getCSSPrimitiveTypeString(stringType)) + + if self._primitiveType != stringType: + raise xml.dom.InvalidAccessErr( + u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r' + % (self.primitiveTypeString, + self._getCSSPrimitiveTypeString(stringType))) + + if CSSPrimitiveValue.CSS_STRING == self._primitiveType: + self.cssText = u'"%s"' % stringValue.replace(u'"', ur'\\"') + elif CSSPrimitiveValue.CSS_URI == self._primitiveType: + # Some characters appearing in an unquoted URI, such as + # parentheses, commas, whitespace characters, single quotes + # (') and double quotes ("), must be escaped with a backslash + # so that the resulting URI value is a URI token: + # '\(', '\)', '\,'. + # + # Here the URI is set in quotes alltogether! + if u'(' in stringValue or\ + u')' in stringValue or\ + u',' in stringValue or\ + u'"' in stringValue or\ + u'\'' in stringValue or\ + u'\n' in stringValue or\ + u'\t' in stringValue or\ + u'\r' in stringValue or\ + u'\f' in stringValue or\ + u' ' in stringValue: + stringValue = '"%s"' % stringValue.replace(u'"', ur'\"') + self.cssText = u'url(%s)' % stringValue + elif CSSPrimitiveValue.CSS_ATTR == self._primitiveType: + self.cssText = u'attr(%s)' % stringValue + else: + self.cssText = stringValue + self._primitiveType = stringType + + def getCounterValue(self): + """ + (DOM method) This method is used to get the Counter value. If + this CSS value doesn't contain a counter value, a DOMException + is raised. Modification to the corresponding style property + can be achieved using the Counter interface. + """ + if not self.CSS_COUNTER == self.primitiveType: + raise xml.dom.InvalidAccessErr(u'Value is not a counter type') + # TODO: use Counter class + raise NotImplementedError() + + def getRGBColorValue(self): + """ + (DOM method) This method is used to get the RGB color. If this + CSS value doesn't contain a RGB color value, a DOMException + is raised. Modification to the corresponding style property + can be achieved using the RGBColor interface. + """ + # TODO: what about coercing #000 to RGBColor? + if self.primitiveType not in self._rbgtypes: + raise xml.dom.InvalidAccessErr(u'Value is not a RGB value') + # TODO: use RGBColor class + raise NotImplementedError() + + def getRectValue(self): + """ + (DOM method) This method is used to get the Rect value. If this CSS + value doesn't contain a rect value, a DOMException is raised. + Modification to the corresponding style property can be achieved + using the Rect interface. + """ + if self.primitiveType not in self._recttypes: + raise xml.dom.InvalidAccessErr(u'value is not a Rect value') + # TODO: use Rect class + raise NotImplementedError() + + def _getCssText(self): + """overwritten from CSSValue""" + return cssutils.ser.do_css_CSSPrimitiveValue(self) + + def _setCssText(self, cssText): + """use CSSValue's implementation""" + return super(CSSPrimitiveValue, self)._setCssText(cssText) + + cssText = property(_getCssText, _setCssText, + doc="A string representation of the current value.") + + def __str__(self): + return "<cssutils.css.%s object primitiveType=%s cssText=%r _propertyName=%r valid=%r at 0x%x>" % ( + self.__class__.__name__, self.primitiveTypeString, + self.cssText, self._propertyName, self.valid, id(self)) + + +class CSSValueList(CSSValue): + """ + The CSSValueList interface provides the abstraction of an ordered + collection of CSS values. + + Some properties allow an empty list into their syntax. In that case, + these properties take the none identifier. So, an empty list means + that the property has the value none. + + The items in the CSSValueList are accessible via an integral index, + starting from 0. + """ + cssValueType = CSSValue.CSS_VALUE_LIST + + def __init__(self, cssText=None, readonly=False, _propertyName=None): + """ + inits a new CSSValueList + """ + super(CSSValueList, self).__init__(cssText=cssText, + readonly=readonly, + _propertyName=_propertyName) + self._init() + + def _init(self): + "called by CSSValue if newly identified as CSSValueList" + # defines which values + ivalueseq, valueseq = 0, self._SHORTHANDPROPERTIES.get( + self._propertyName, []) + self._items = [] + newseq = self._tempSeq(False) + i, max = 0, len(self.seq) + minus = None + while i < max: + item = self.seq[i] + type_, val, line, col = item.type, item.value, item.line, item.col + if u'-' == val: + if minus: # 2 "-" after another + self._log.error( # TODO: + u'CSSValueList: Unknown syntax: %r.' + % u''.join(self.seq)) + else: + minus = val + + elif isinstance(val, basestring) and not type_ == 'separator' and\ + not u'/' == val: + if minus: + val = minus + val + minus = None + # TODO: complete + # if shorthand get new propname + if ivalueseq < len(valueseq): + propname, mandatory = valueseq[ivalueseq] + if mandatory: + ivalueseq += 1 + else: + propname = None + ivalueseq = len(valueseq) # end + else: + propname = self._propertyName + + # TODO: more (do not check individual values for these props) + if propname in self._SHORTHANDPROPERTIES: + propname = None + + if i+1 < max and self.seq[i+1].value == u',': + # a comma separated list of values as ONE value + # e.g. font-family: a,b + # CSSValue already has removed extra S tokens! + fullvalue = [val] + + expected = 'comma' # or 'value' + for j in range(i+1, max): + item2 = self.seq[j] + typ2, val2, line2, col2 = (item2.type, item2.value, + item2.line, item2.col) + if u' ' == val2: + # end or a single value follows + break + elif 'value' == expected and val2 in u'-+': + # unary modifier + fullvalue.append(val2) + expected = 'value' + elif 'comma' == expected and u',' == val2: + fullvalue.append(val2) + expected = 'value' + elif 'value' == expected and u',' != val2: + if 'STRING' == typ2: + val2 = cssutils.ser._string(val2) + fullvalue.append(val2) + expected = 'comma' + else: + self._log.error( + u'CSSValueList: Unknown syntax: %r.' + % val2) + return + if expected == 'value': + self._log.error( # TODO: + u'CSSValueList: Unknown syntax: %r.' + % u''.join(self.seq)) + return + # setting _propertyName this way does not work + # for compound props like font! + i += len(fullvalue) - 1 + obj = CSSValue(cssText=u''.join(fullvalue), + _propertyName=propname) + else: + # a single value, u' ' or nothing should be following + if 'STRING' == type_: + val = cssutils.ser._string(val) + elif 'URI' == type_: + val = cssutils.ser._uri(val) + + obj = CSSValue(cssText=val, _propertyName=propname) + + self._items.append(obj) + newseq.append(obj, CSSValue) + + elif CSSColor == type_: + self._items.append(val) + newseq.append(val, CSSColor) + + else: + # S (or TODO: comment?) + newseq.append(val, type_) + + i += 1 + + self._setSeq(newseq) + + length = property(lambda self: len(self._items), + doc="(DOM attribute) The number of CSSValues in the list.") + + def item(self, index): + """ + (DOM method) Used to retrieve a CSSValue by ordinal index. The + order in this collection represents the order of the values in the + CSS style property. If index is greater than or equal to the number + of values in the list, this returns None. + """ + try: + return self._items[index] + except IndexError: + return None + + def __iter__(self): + "CSSValueList is iterable" + return CSSValueList.__items(self) + + def __items(self): + "the iterator" + for i in range (0, self.length): + yield self.item(i) + + def __str__(self): + return "<cssutils.css.%s object cssValueType=%r cssText=%r length=%r propname=%r valid=%r at 0x%x>" % ( + self.__class__.__name__, self.cssValueTypeString, + self.cssText, self.length, self._propertyName, + self.valid, id(self)) + + +class CSSFunction(CSSPrimitiveValue): + """A CSS function value like rect() etc.""" + + def __init__(self, cssText=None, readonly=False): + """ + Init a new CSSFunction + + cssText + the parsable cssText of the value + readonly + defaults to False + """ + super(CSSColor, self).__init__() + self.valid = False + self.wellformed = False + if cssText is not None: + self.cssText = cssText + + self._funcType = None + + self._readonly = readonly + + def _setCssText(self, cssText): + self._checkReadonly() + if False: + pass + else: + types = self._prods # rename! + valueProd = Prod(name='value', + match=lambda t, v: t in (types.NUMBER, types.PERCENTAGE), + toSeq=CSSPrimitiveValue, + toStore='parts' + ) + # COLOR PRODUCTION + funcProds = Sequence([ + Prod(name='FUNC', + match=lambda t, v: t == types.FUNCTION, + toStore='funcType' ), + Prod(**PreDef.sign), + valueProd, + # more values starting with Comma + # should use store where colorType is saved to + # define min and may, closure? + Sequence([Prod(**PreDef.comma), + Prod(**PreDef.sign), + valueProd], + minmax=lambda: (2, 2)), + Prod(**PreDef.funcEnd) + ]) + # store: colorType, parts + wellformed, seq, store, unusedtokens = ProdsParser().parse(cssText, + u'CSSFunction', + funcProds, + {'parts': []}) + + if wellformed: + self.wellformed = True + self._setSeq(seq) + self._funcType = self._normalize(store['colorType'].value[:-1]) + + cssText = property(lambda self: cssutils.ser.do_css_CSSColor(self), + _setCssText) + + funcType = property(lambda self: self._funcType) + + def __repr__(self): + return "cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText) + + def __str__(self): + return "<cssutils.css.%s object colorType=%r cssText=%r at 0x%x>" % ( + self.__class__.__name__, self.colorType, self.cssText, + id(self)) + + + + +class CSSColor(CSSPrimitiveValue): + """A CSS color like RGB, RGBA or a simple value like `#000` or `red`.""" + + def __init__(self, cssText=None, readonly=False): + """ + Init a new CSSColor + + cssText + the parsable cssText of the value + readonly + defaults to False + """ + super(CSSColor, self).__init__() + self._colorType = None + self.valid = False + self.wellformed = False + if cssText is not None: + self.cssText = cssText + + self._readonly = readonly + + def _setCssText(self, cssText): + self._checkReadonly() + if False: + pass + else: + types = self._prods # rename! + valueProd = Prod(name='value', + match=lambda t, v: t in (types.NUMBER, types.PERCENTAGE), + toSeq=CSSPrimitiveValue, + toStore='parts' + ) + # COLOR PRODUCTION + funccolor = Sequence([Prod(name='FUNC', + match=lambda t, v: self._normalize(v) in ('rgb(', 'rgba(', 'hsl(', 'hsla(') and t == types.FUNCTION, + toSeq=lambda v: self._normalize(v), + toStore='colorType' ), + PreDef.unary(), + valueProd, + # 2 or 3 more values starting with Comma + Sequence([PreDef.comma(), + PreDef.unary(), + valueProd], + minmax=lambda: (2,3)), + PreDef.funcEnd() + ] + ) + colorprods = Choice([funccolor, + Prod(name='HEX color', + match=lambda t, v: t == types.HASH and + len(v) == 4 or len(v) == 7, + toStore='colorType' + ), + Prod(name='named color', + match=lambda t, v: t == types.IDENT, + toStore='colorType' + ), + ] + ) + # store: colorType, parts + wellformed, seq, store, unusedtokens = ProdParser().parse(cssText, + u'CSSColor', + colorprods, + {'parts': []}) + + if wellformed: + self.wellformed = True + if store['colorType'].type == self._prods.HASH: + self._colorType = 'HEX' + elif store['colorType'].type == self._prods.IDENT: + self._colorType = 'Named Color' + else: + self._colorType = self._normalize(store['colorType'].value)[:-1] + + self._setSeq(seq) + + cssText = property(lambda self: cssutils.ser.do_css_CSSColor(self), + _setCssText) + + colorType = property(lambda self: self._colorType) + + def __repr__(self): + return "cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText) + + def __str__(self): + return "<cssutils.css.%s object colorType=%r cssText=%r at 0x%x>" % ( + self.__class__.__name__, self.colorType, self.cssText, + id(self)) diff --git a/src/cssutils/css/property.py b/src/cssutils/css/property.py new file mode 100644 index 0000000000..9d8cd07932 --- /dev/null +++ b/src/cssutils/css/property.py @@ -0,0 +1,415 @@ +"""Property is a single CSS property in a CSSStyleDeclaration + +Internal use only, may be removed in the future! +""" +__all__ = ['Property'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: property.py 1444 2008-08-31 18:45:35Z cthedot $' + +import xml.dom +import cssutils +#import cssproperties +from cssutils.profiles import profiles +from cssvalue import CSSValue +from cssutils.helper import Deprecated + +class Property(cssutils.util.Base): + """ + (cssutils) a CSS property in a StyleDeclaration of a CSSStyleRule + + Properties + ========== + cssText + a parsable textual representation of this property + name + normalized name of the property, e.g. "color" when name is "c\olor" + (since 0.9.5) + literalname (since 0.9.5) + original name of the property in the source CSS which is not normalized + e.g. "C\\OLor" + cssValue + the relevant CSSValue instance for this property + value + the string value of the property, same as cssValue.cssText + priority + of the property (currently only u"important" or None) + literalpriority + original priority of the property in the source CSS which is not + normalized e.g. "IM\portant" + seqs + combination of a list for seq of name, a CSSValue object, and + a list for seq of priority (empty or [!important] currently) + valid + if this Property is valid + wellformed + if this Property is syntactically ok + + DEPRECATED normalname (since 0.9.5) + normalized name of the property, e.g. "color" when name is "c\olor" + + Format + ====== + :: + + property = name + : IDENT S* + ; + + expr = value + : term [ operator term ]* + ; + term + : unary_operator? + [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | + TIME S* | FREQ S* | function ] + | STRING S* | IDENT S* | URI S* | hexcolor + ; + function + : FUNCTION S* expr ')' S* + ; + /* + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + */ + hexcolor + : HASH S* + ; + + prio + : IMPORTANT_SYM S* + ; + + """ + def __init__(self, name=None, value=None, priority=u'', _mediaQuery=False): + """ + inits property + + name + a property name string (will be normalized) + value + a property value string + priority + an optional priority string which currently must be u'', + u'!important' or u'important' + _mediaQuery boolean + if True value is optional as used by MediaQuery objects + """ + super(Property, self).__init__() + + self.seqs = [[], None, []] + self.valid = False + self.wellformed = False + self._mediaQuery = _mediaQuery + + if name: + self.name = name + else: + self._name = u'' + self._literalname = u'' + self.__normalname = u'' # DEPRECATED + + if value: + self.cssValue = value + else: + self.seqs[1] = CSSValue() + + if priority: + self.priority = priority + else: + self._priority = u'' + self._literalpriority = u'' + + def _getCssText(self): + """ + returns serialized property cssText + """ + return cssutils.ser.do_Property(self) + + def _setCssText(self, cssText): + """ + DOMException on setting + + - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) + Raised if the rule is readonly. + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error and + is unparsable. + """ + # check and prepare tokenlists for setting + tokenizer = self._tokenize2(cssText) + nametokens = self._tokensupto2(tokenizer, propertynameendonly=True) + if nametokens: + wellformed = True + + valuetokens = self._tokensupto2(tokenizer, + propertyvalueendonly=True) + prioritytokens = self._tokensupto2(tokenizer, + propertypriorityendonly=True) + + if self._mediaQuery and not valuetokens: + # MediaQuery may consist of name only + self.name = nametokens + self.cssValue = None + self.priority = None + return + + # remove colon from nametokens + colontoken = nametokens.pop() + if self._tokenvalue(colontoken) != u':': + wellformed = False + self._log.error(u'Property: No ":" after name found: %r' % + self._valuestr(cssText), colontoken) + elif not nametokens: + wellformed = False + self._log.error(u'Property: No property name found: %r.' % + self._valuestr(cssText), colontoken) + + if valuetokens: + if self._tokenvalue(valuetokens[-1]) == u'!': + # priority given, move "!" to prioritytokens + prioritytokens.insert(0, valuetokens.pop(-1)) + else: + wellformed = False + self._log.error(u'Property: No property value found: %r.' % + self._valuestr(cssText), colontoken) + + if wellformed: + self.wellformed = True + self.name = nametokens + self.cssValue = valuetokens + self.priority = prioritytokens + + else: + self._log.error(u'Property: No property name found: %r.' % + self._valuestr(cssText)) + + cssText = property(fget=_getCssText, fset=_setCssText, + doc="A parsable textual representation.") + + def _setName(self, name): + """ + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified name has a syntax error and is + unparsable. + """ + # for closures: must be a mutable + new = {'literalname': None, + 'wellformed': True} + + def _ident(expected, seq, token, tokenizer=None): + # name + if 'name' == expected: + new['literalname'] = self._tokenvalue(token).lower() + seq.append(new['literalname']) + return 'EOF' + else: + new['wellformed'] = False + self._log.error(u'Property: Unexpected ident.', token) + return expected + + newseq = [] + wellformed, expected = self._parse(expected='name', + seq=newseq, + tokenizer=self._tokenize2(name), + productions={'IDENT': _ident}) + wellformed = wellformed and new['wellformed'] + + # post conditions + # define a token for error logging + if isinstance(name, list): + token = name[0] + else: + token = None + + if not new['literalname']: + wellformed = False + self._log.error(u'Property: No name found: %r' % + self._valuestr(name), token=token) + + if wellformed: + self.wellformed = True + self._literalname = new['literalname'] + self._name = self._normalize(self._literalname) + self.__normalname = self._name # DEPRECATED + self.seqs[0] = newseq + + # validate + if self._name not in profiles.propertiesByProfile(): + self.valid = False + tokenizer=self._tokenize2(name) + self._log.warn(u'Property: Unknown Property: %r.' % + new['literalname'], token=token, neverraise=True) + else: + self.valid = True + if self.cssValue: + self.cssValue._propertyName = self._name + self.valid = self.cssValue.valid + else: + self.wellformed = False + + name = property(lambda self: self._name, _setName, + doc="Name of this property") + + literalname = property(lambda self: self._literalname, + doc="Readonly literal (not normalized) name of this property") + + def _getCSSValue(self): + return self.seqs[1] + + def _setCSSValue(self, cssText): + """ + see css.CSSValue + + DOMException on setting? + + - SYNTAX_ERR: (self) + Raised if the specified CSS string value has a syntax error + (according to the attached property) or is unparsable. + - TODO: INVALID_MODIFICATION_ERR: + Raised if the specified CSS string value represents a different + type of values than the values allowed by the CSS property. + """ + if self._mediaQuery and not cssText: + self.seqs[1] = CSSValue() + else: + if not self.seqs[1]: + self.seqs[1] = CSSValue() + + cssvalue = self.seqs[1] + cssvalue._propertyName = self.name + cssvalue.cssText = cssText + if cssvalue._value and cssvalue.wellformed: + self.seqs[1] = cssvalue + self.valid = self.valid and cssvalue.valid + self.wellformed = self.wellformed and cssvalue.wellformed + + cssValue = property(_getCSSValue, _setCSSValue, + doc="(cssutils) CSSValue object of this property") + + def _getValue(self): + if self.cssValue: + return self.cssValue._value + else: + return u'' + + def _setValue(self, value): + self.cssValue.cssText = value + self.valid = self.valid and self.cssValue.valid + self.wellformed = self.wellformed and self.cssValue.wellformed + + value = property(_getValue, _setValue, + doc="The textual value of this Properties cssValue.") + + def _setPriority(self, priority): + """ + priority + a string, currently either u'', u'!important' or u'important' + + Format + ====== + :: + + prio + : IMPORTANT_SYM S* + ; + + "!"{w}"important" {return IMPORTANT_SYM;} + + DOMException on setting + + - SYNTAX_ERR: (self) + Raised if the specified priority has a syntax error and is + unparsable. + In this case a priority not equal to None, "" or "!{w}important". + As CSSOM defines CSSStyleDeclaration.getPropertyPriority resulting in + u'important' this value is also allowed to set a Properties priority + """ + if self._mediaQuery: + self._priority = u'' + self._literalpriority = u'' + if priority: + self._log.error(u'Property: No priority in a MediaQuery - ignored.') + return + + if isinstance(priority, basestring) and\ + u'important' == self._normalize(priority): + priority = u'!%s' % priority + + # for closures: must be a mutable + new = {'literalpriority': u'', + 'wellformed': True} + + def _char(expected, seq, token, tokenizer=None): + # "!" + val = self._tokenvalue(token) + if u'!' == expected == val: + seq.append(val) + return 'important' + else: + new['wellformed'] = False + self._log.error(u'Property: Unexpected char.', token) + return expected + + def _ident(expected, seq, token, tokenizer=None): + # "important" + val = self._tokenvalue(token) + normalval = self._tokenvalue(token, normalize=True) + if 'important' == expected == normalval: + new['literalpriority'] = val + seq.append(val) + return 'EOF' + else: + new['wellformed'] = False + self._log.error(u'Property: Unexpected ident.', token) + return expected + + newseq = [] + wellformed, expected = self._parse(expected='!', + seq=newseq, + tokenizer=self._tokenize2(priority), + productions={'CHAR': _char, + 'IDENT': _ident}) + wellformed = wellformed and new['wellformed'] + + # post conditions + if priority and not new['literalpriority']: + wellformed = False + self._log.info(u'Property: Invalid priority: %r.' % + self._valuestr(priority)) + + if wellformed: + self.wellformed = self.wellformed and wellformed + self._literalpriority = new['literalpriority'] + self._priority = self._normalize(self.literalpriority) + self.seqs[2] = newseq + + # validate + if self._priority not in (u'', u'important'): + self.valid = False + self._log.info(u'Property: No CSS2 priority value: %r.' % + self._priority, neverraise=True) + + priority = property(lambda self: self._priority, _setPriority, + doc="(cssutils) Priority of this property") + + literalpriority = property(lambda self: self._literalpriority, + doc="Readonly literal (not normalized) priority of this property") + + def __repr__(self): + return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % ( + self.__class__.__name__, + self.literalname, self.cssValue.cssText, self.priority) + + def __str__(self): + return "<%s.%s object name=%r value=%r priority=%r at 0x%x>" % ( + self.__class__.__module__, self.__class__.__name__, + self.name, self.cssValue.cssText, self.priority, id(self)) + + @Deprecated(u'Use property ``name`` instead (since cssutils 0.9.5).') + def _getNormalname(self): + return self.__normalname + normalname = property(_getNormalname, + doc="DEPRECATED since 0.9.5, use name instead") \ No newline at end of file diff --git a/src/cssutils/css/selector.py b/src/cssutils/css/selector.py new file mode 100644 index 0000000000..3297cc5992 --- /dev/null +++ b/src/cssutils/css/selector.py @@ -0,0 +1,800 @@ +"""Selector is a single Selector of a CSSStyleRule SelectorList. + +Partly implements + http://www.w3.org/TR/css3-selectors/ + +TODO + - .contains(selector) + - .isSubselector(selector) +""" +__all__ = ['Selector'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: selector.py 1429 2008-08-11 19:01:52Z cthedot $' + +import xml.dom +import cssutils +from cssutils.util import _SimpleNamespaces + +class Selector(cssutils.util.Base2): + """ + (cssutils) a single selector in a SelectorList of a CSSStyleRule + + Properties + ========== + element + Effective element target of this selector + parentList: of type SelectorList, readonly + The SelectorList that contains this selector or None if this + Selector is not attached to a SelectorList. + selectorText + textual representation of this Selector + seq + sequence of Selector parts including comments + specificity (READONLY) + tuple of (a, b, c, d) where: + + a + presence of style in document, always 0 if not used on a document + b + number of ID selectors + c + number of .class selectors + d + number of Element (type) selectors + + wellformed + if this selector is wellformed regarding the Selector spec + + Format + ====== + :: + + # implemented in SelectorList + selectors_group + : selector [ COMMA S* selector ]* + ; + + selector + : simple_selector_sequence [ combinator simple_selector_sequence ]* + ; + + combinator + /* combinators can be surrounded by white space */ + : PLUS S* | GREATER S* | TILDE S* | S+ + ; + + simple_selector_sequence + : [ type_selector | universal ] + [ HASH | class | attrib | pseudo | negation ]* + | [ HASH | class | attrib | pseudo | negation ]+ + ; + + type_selector + : [ namespace_prefix ]? element_name + ; + + namespace_prefix + : [ IDENT | '*' ]? '|' + ; + + element_name + : IDENT + ; + + universal + : [ namespace_prefix ]? '*' + ; + + class + : '.' IDENT + ; + + attrib + : '[' S* [ namespace_prefix ]? IDENT S* + [ [ PREFIXMATCH | + SUFFIXMATCH | + SUBSTRINGMATCH | + '=' | + INCLUDES | + DASHMATCH ] S* [ IDENT | STRING ] S* + ]? ']' + ; + + pseudo + /* '::' starts a pseudo-element, ':' a pseudo-class */ + /* Exceptions: :first-line, :first-letter, :before and :after. */ + /* Note that pseudo-elements are restricted to one per selector and */ + /* occur only in the last simple_selector_sequence. */ + : ':' ':'? [ IDENT | functional_pseudo ] + ; + + functional_pseudo + : FUNCTION S* expression ')' + ; + + expression + /* In CSS3, the expressions are identifiers, strings, */ + /* or of the form "an+b" */ + : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ + ; + + negation + : NOT S* negation_arg S* ')' + ; + + negation_arg + : type_selector | universal | HASH | class | attrib | pseudo + ; + + """ + def __init__(self, selectorText=None, parentList=None, + readonly=False): + """ + :Parameters: + selectorText + initial value of this selector + parentList + a SelectorList + readonly + default to False + """ + super(Selector, self).__init__() + + self.__namespaces = _SimpleNamespaces(log=self._log) + self._element = None + self._parent = parentList + self._specificity = (0, 0, 0, 0) + + if selectorText: + self.selectorText = selectorText + + self._readonly = readonly + + def __getNamespaces(self): + "uses own namespaces if not attached to a sheet, else the sheet's ones" + try: + return self._parent.parentRule.parentStyleSheet.namespaces + except AttributeError: + return self.__namespaces + + _namespaces = property(__getNamespaces, doc="""if this Selector is attached + to a CSSStyleSheet the namespaces of that sheet are mirrored here. + While the Selector (or parent SelectorList or parentRule(s) of that are + not attached a own dict of {prefix: namespaceURI} is used.""") + + + element = property(lambda self: self._element, + doc=u"Effective element target of this selector.") + + parentList = property(lambda self: self._parent, + doc="(DOM) The SelectorList that contains this Selector or\ + None if this Selector is not attached to a SelectorList.") + + def _getSelectorText(self): + """ + returns serialized format + """ + return cssutils.ser.do_css_Selector(self) + + def _setSelectorText(self, selectorText): + """ + :param selectorText: + parsable string or a tuple of (selectorText, dict-of-namespaces). + Given namespaces are ignored if this object is attached to a + CSSStyleSheet! + + :Exceptions: + - `NAMESPACE_ERR`: (self) + Raised if the specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (self) + Raised if the specified CSS string value has a syntax error + and is unparsable. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this rule is readonly. + """ + self._checkReadonly() + + # might be (selectorText, namespaces) + selectorText, namespaces = self._splitNamespacesOff(selectorText) + + try: + # uses parent stylesheets namespaces if available, otherwise given ones + namespaces = self.parentList.parentRule.parentStyleSheet.namespaces + except AttributeError: + pass + tokenizer = self._tokenize2(selectorText) + if not tokenizer: + self._log.error(u'Selector: No selectorText given.') + else: + # prepare tokenlist: + # "*" -> type "universal" + # "*"|IDENT + "|" -> combined to "namespace_prefix" + # "|" -> type "namespace_prefix" + # "." + IDENT -> combined to "class" + # ":" + IDENT, ":" + FUNCTION -> pseudo-class + # FUNCTION "not(" -> negation + # "::" + IDENT, "::" + FUNCTION -> pseudo-element + tokens = [] + for t in tokenizer: + typ, val, lin, col = t + if val == u':' and tokens and\ + self._tokenvalue(tokens[-1]) == ':': + # combine ":" and ":" + tokens[-1] = (typ, u'::', lin, col) + + elif typ == 'IDENT' and tokens\ + and self._tokenvalue(tokens[-1]) == u'.': + # class: combine to .IDENT + tokens[-1] = ('class', u'.'+val, lin, col) + elif typ == 'IDENT' and tokens and \ + self._tokenvalue(tokens[-1]).startswith(u':') and\ + not self._tokenvalue(tokens[-1]).endswith(u'('): + # pseudo-X: combine to :IDENT or ::IDENT but not ":a(" + "b" + if self._tokenvalue(tokens[-1]).startswith(u'::'): + t = 'pseudo-element' + else: + t = 'pseudo-class' + tokens[-1] = (t, self._tokenvalue(tokens[-1])+val, lin, col) + + elif typ == 'FUNCTION' and val == u'not(' and tokens and \ + u':' == self._tokenvalue(tokens[-1]): + tokens[-1] = ('negation', u':' + val, lin, tokens[-1][3]) + elif typ == 'FUNCTION' and tokens\ + and self._tokenvalue(tokens[-1]).startswith(u':'): + # pseudo-X: combine to :FUNCTION( or ::FUNCTION( + if self._tokenvalue(tokens[-1]).startswith(u'::'): + t = 'pseudo-element' + else: + t = 'pseudo-class' + tokens[-1] = (t, self._tokenvalue(tokens[-1])+val, lin, col) + + elif val == u'*' and tokens and\ + self._type(tokens[-1]) == 'namespace_prefix' and\ + self._tokenvalue(tokens[-1]).endswith(u'|'): + # combine prefix|* + tokens[-1] = ('universal', self._tokenvalue(tokens[-1])+val, + lin, col) + elif val == u'*': + # universal: "*" + tokens.append(('universal', val, lin, col)) + + elif val == u'|' and tokens and\ + self._type(tokens[-1]) in (self._prods.IDENT, 'universal') and\ + self._tokenvalue(tokens[-1]).find(u'|') == -1: + # namespace_prefix: "IDENT|" or "*|" + tokens[-1] = ('namespace_prefix', + self._tokenvalue(tokens[-1])+u'|', lin, col) + elif val == u'|': + # namespace_prefix: "|" + tokens.append(('namespace_prefix', val, lin, col)) + + else: + tokens.append(t) + + # TODO: back to generator but not elegant at all! + tokenizer = (t for t in tokens) + + # for closures: must be a mutable + new = {'context': [''], # stack of: 'attrib', 'negation', 'pseudo' + 'element': None, + '_PREFIX': None, + 'specificity': [0, 0, 0, 0], # mutable, finally a tuple! + 'wellformed': True + } + # used for equality checks and setting of a space combinator + S = u' ' + + def append(seq, val, typ=None, token=None): + """ + appends to seq + + namespace_prefix, IDENT will be combined to a tuple + (prefix, name) where prefix might be None, the empty string + or a prefix. + + Saved are also: + - specificity definition: style, id, class/att, type + - element: the element this Selector is for + """ + context = new['context'][-1] + if token: + line, col = token[2], token[3] + else: + line, col = None, None + + if typ == '_PREFIX': + # SPECIAL TYPE: save prefix for combination with next + new['_PREFIX'] = val[:-1] + # handle next time + return + + if new['_PREFIX'] is not None: + # as saved from before and reset to None + prefix, new['_PREFIX'] = new['_PREFIX'], None + elif typ == 'universal' and '|' in val: + # val == *|* or prefix|* + prefix, val = val.split('|') + else: + prefix = None + + # namespace + if (typ.endswith('-selector') or typ == 'universal') and not ( + 'attribute-selector' == typ and not prefix): + # att **IS NOT** in default ns + if prefix == u'*': + # *|name: in ANY_NS + namespaceURI = cssutils._ANYNS + elif prefix is None: + # e or *: default namespace with prefix u'' or local-name() + namespaceURI = namespaces.get(u'', None) + elif prefix == u'': + # |name or |*: in no (or the empty) namespace + namespaceURI = u'' + else: + # explicit namespace prefix + # does not raise KeyError, see _SimpleNamespaces + namespaceURI = namespaces[prefix] + + if namespaceURI is None: + new['wellformed'] = False + self._log.error( + u'Selector: No namespaceURI found for prefix %r' % + prefix, token=token, error=xml.dom.NamespaceErr) + return + + # val is now (namespaceprefix, name) tuple + val = (namespaceURI, val) + + # specificity + if not context or context == 'negation': + if 'id' == typ: + new['specificity'][1] += 1 + elif 'class' == typ or '[' == val: + new['specificity'][2] += 1 + elif typ in ('type-selector', 'negation-type-selector', + 'pseudo-element'): + new['specificity'][3] += 1 + if not context and typ in ('type-selector', 'universal'): + # define element + new['element'] = val + + seq.append(val, typ, line=line, col=col) + + # expected constants + simple_selector_sequence = 'type_selector universal HASH class attrib pseudo negation ' + simple_selector_sequence2 = 'HASH class attrib pseudo negation ' + + element_name = 'element_name' + + negation_arg = 'type_selector universal HASH class attrib pseudo' + negationend = ')' + + attname = 'prefix attribute' + attname2 = 'attribute' + attcombinator = 'combinator ]' # optional + attvalue = 'value' # optional + attend = ']' + + expressionstart = 'PLUS - DIMENSION NUMBER STRING IDENT' + expression = expressionstart + ' )' + + combinator = ' combinator' + + def _COMMENT(expected, seq, token, tokenizer=None): + "special implementation for comment token" + append(seq, cssutils.css.CSSComment([token]), 'COMMENT', + token=token) + return expected + + def _S(expected, seq, token, tokenizer=None): + # S + context = new['context'][-1] + if context.startswith('pseudo-'): + if seq and seq[-1].value not in u'+-': + # e.g. x:func(a + b) + append(seq, S, 'S', token=token) + return expected + + elif context != 'attrib' and 'combinator' in expected: + append(seq, S, 'descendant', token=token) + return simple_selector_sequence + combinator + + else: + return expected + + def _universal(expected, seq, token, tokenizer=None): + # *|* or prefix|* + context = new['context'][-1] + val = self._tokenvalue(token) + if 'universal' in expected: + append(seq, val, 'universal', token=token) + + if 'negation' == context: + return negationend + else: + return simple_selector_sequence2 + combinator + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected universal.', token=token) + return expected + + def _namespace_prefix(expected, seq, token, tokenizer=None): + # prefix| => element_name + # or prefix| => attribute_name if attrib + context = new['context'][-1] + val = self._tokenvalue(token) + if 'attrib' == context and 'prefix' in expected: + # [PREFIX|att] + append(seq, val, '_PREFIX', token=token) + return attname2 + elif 'type_selector' in expected: + # PREFIX|* + append(seq, val, '_PREFIX', token=token) + return element_name + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected namespace prefix.', token=token) + return expected + + def _pseudo(expected, seq, token, tokenizer=None): + # pseudo-class or pseudo-element :a ::a :a( ::a( + """ + /* '::' starts a pseudo-element, ':' a pseudo-class */ + /* Exceptions: :first-line, :first-letter, :before and :after. */ + /* Note that pseudo-elements are restricted to one per selector and */ + /* occur only in the last simple_selector_sequence. */ + """ + context = new['context'][-1] + val, typ = self._tokenvalue(token, normalize=True), self._type(token) + if 'pseudo' in expected: + if val in (':first-line', ':first-letter', ':before', ':after'): + # always pseudo-element ??? + typ = 'pseudo-element' + append(seq, val, typ, token=token) + + if val.endswith(u'('): + # function + new['context'].append(typ) # "pseudo-" "class" or "element" + return expressionstart + elif 'negation' == context: + return negationend + elif 'pseudo-element' == typ: + # only one per element, check at ) also! + return combinator + else: + return simple_selector_sequence2 + combinator + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected start of pseudo.', token=token) + return expected + + def _expression(expected, seq, token, tokenizer=None): + # [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ + context = new['context'][-1] + val, typ = self._tokenvalue(token), self._type(token) + if context.startswith('pseudo-'): + append(seq, val, typ, token=token) + return expression + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected %s.' % typ, token=token) + return expected + + def _attcombinator(expected, seq, token, tokenizer=None): + # context: attrib + # PREFIXMATCH | SUFFIXMATCH | SUBSTRINGMATCH | INCLUDES | + # DASHMATCH + context = new['context'][-1] + val, typ = self._tokenvalue(token), self._type(token) + if 'attrib' == context and 'combinator' in expected: + # combinator in attrib + append(seq, val, typ.lower(), token=token) + return attvalue + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected %s.' % typ, token=token) + return expected + + def _string(expected, seq, token, tokenizer=None): + # identifier + context = new['context'][-1] + typ, val = self._type(token), self._stringtokenvalue(token) + + # context: attrib + if 'attrib' == context and 'value' in expected: + # attrib: [...=VALUE] + append(seq, val, typ, token=token) + return attend + + # context: pseudo + elif context.startswith('pseudo-'): + # :func(...) + append(seq, val, typ, token=token) + return expression + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected STRING.', token=token) + return expected + + def _ident(expected, seq, token, tokenizer=None): + # identifier + context = new['context'][-1] + val, typ = self._tokenvalue(token), self._type(token) + + # context: attrib + if 'attrib' == context and 'attribute' in expected: + # attrib: [...|ATT...] + append(seq, val, 'attribute-selector', token=token) + return attcombinator + + elif 'attrib' == context and 'value' in expected: + # attrib: [...=VALUE] + append(seq, val, 'attribute-value', token=token) + return attend + + # context: negation + elif 'negation' == context: + # negation: (prefix|IDENT) + append(seq, val, 'negation-type-selector', token=token) + return negationend + + # context: pseudo + elif context.startswith('pseudo-'): + # :func(...) + append(seq, val, typ, token=token) + return expression + + elif 'type_selector' in expected or element_name == expected: + # element name after ns or complete type_selector + append(seq, val, 'type-selector', token=token) + return simple_selector_sequence2 + combinator + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected IDENT.', + token=token) + return expected + + def _class(expected, seq, token, tokenizer=None): + # .IDENT + context = new['context'][-1] + val = self._tokenvalue(token) + if 'class' in expected: + append(seq, val, 'class', token=token) + + if 'negation' == context: + return negationend + else: + return simple_selector_sequence2 + combinator + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected class.', token=token) + return expected + + def _hash(expected, seq, token, tokenizer=None): + # #IDENT + context = new['context'][-1] + val = self._tokenvalue(token) + if 'HASH' in expected: + append(seq, val, 'id', token=token) + + if 'negation' == context: + return negationend + else: + return simple_selector_sequence2 + combinator + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected HASH.', token=token) + return expected + + def _char(expected, seq, token, tokenizer=None): + # + > ~ ) [ ] + - + context = new['context'][-1] + val = self._tokenvalue(token) + + # context: attrib + if u']' == val and 'attrib' == context and ']' in expected: + # end of attrib + append(seq, val, 'attribute-end', token=token) + context = new['context'].pop() # attrib is done + context = new['context'][-1] + if 'negation' == context: + return negationend + else: + return simple_selector_sequence2 + combinator + + elif u'=' == val and 'attrib' == context and 'combinator' in expected: + # combinator in attrib + append(seq, val, 'equals', token=token) + return attvalue + + # context: negation + elif u')' == val and 'negation' == context and u')' in expected: + # not(negation_arg)" + append(seq, val, 'negation-end', token=token) + new['context'].pop() # negation is done + context = new['context'][-1] + return simple_selector_sequence + combinator + + # context: pseudo (at least one expression) + elif val in u'+-' and context.startswith('pseudo-'): + # :func(+ -)" + _names = {'+': 'plus', '-': 'minus'} + if val == u'+' and seq and seq[-1].value == S: + seq.replace(-1, val, _names[val]) + else: + append(seq, val, _names[val], + token=token) + return expression + + elif u')' == val and context.startswith('pseudo-') and\ + expression == expected: + # :func(expression)" + append(seq, val, 'function-end', token=token) + new['context'].pop() # pseudo is done + if 'pseudo-element' == context: + return combinator + else: + return simple_selector_sequence + combinator + + # context: ROOT + elif u'[' == val and 'attrib' in expected: + # start of [attrib] + append(seq, val, 'attribute-start', token=token) + new['context'].append('attrib') + return attname + + elif val in u'+>~' and 'combinator' in expected: + # no other combinator except S may be following + _names = { + '>': 'child', + '+': 'adjacent-sibling', + '~': 'following-sibling'} + if seq and seq[-1].value == S: + seq.replace(-1, val, _names[val]) + else: + append(seq, val, _names[val], token=token) + return simple_selector_sequence + + elif u',' == val: + # not a selectorlist + new['wellformed'] = False + self._log.error( + u'Selector: Single selector only.', + error=xml.dom.InvalidModificationErr, + token=token) + return expected + + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected CHAR.', token=token) + return expected + + def _negation(expected, seq, token, tokenizer=None): + # not( + context = new['context'][-1] + val = self._tokenvalue(token, normalize=True) + if 'negation' in expected: + new['context'].append('negation') + append(seq, val, 'negation-start', token=token) + return negation_arg + else: + new['wellformed'] = False + self._log.error( + u'Selector: Unexpected negation.', token=token) + return expected + + # expected: only|not or mediatype, mediatype, feature, and + newseq = self._tempSeq() + + wellformed, expected = self._parse(expected=simple_selector_sequence, + seq=newseq, tokenizer=tokenizer, + productions={'CHAR': _char, + 'class': _class, + 'HASH': _hash, + 'STRING': _string, + 'IDENT': _ident, + 'namespace_prefix': _namespace_prefix, + 'negation': _negation, + 'pseudo-class': _pseudo, + 'pseudo-element': _pseudo, + 'universal': _universal, + # pseudo + 'NUMBER': _expression, + 'DIMENSION': _expression, + # attribute + 'PREFIXMATCH': _attcombinator, + 'SUFFIXMATCH': _attcombinator, + 'SUBSTRINGMATCH': _attcombinator, + 'DASHMATCH': _attcombinator, + 'INCLUDES': _attcombinator, + + 'S': _S, + 'COMMENT': _COMMENT}) + wellformed = wellformed and new['wellformed'] + + # post condition + if len(new['context']) > 1 or not newseq: + wellformed = False + self._log.error(u'Selector: Invalid or incomplete selector: %s' % + self._valuestr(selectorText)) + + if expected == 'element_name': + wellformed = False + self._log.error(u'Selector: No element name found: %s' % + self._valuestr(selectorText)) + + if expected == simple_selector_sequence and newseq: + wellformed = False + self._log.error(u'Selector: Cannot end with combinator: %s' % + self._valuestr(selectorText)) + + if newseq and hasattr(newseq[-1].value, 'strip') and \ + newseq[-1].value.strip() == u'': + del newseq[-1] + + # set + if wellformed: + self.__namespaces = namespaces + self._element = new['element'] + self._specificity = tuple(new['specificity']) + self._setSeq(newseq) + # filter that only used ones are kept + self.__namespaces = self._getUsedNamespaces() + + selectorText = property(_getSelectorText, _setSelectorText, + doc="(DOM) The parsable textual representation of the selector.") + + + specificity = property(lambda self: self._specificity, + doc="Specificity of this selector (READONLY).") + + wellformed = property(lambda self: bool(len(self.seq))) + + def __repr__(self): + if self.__getNamespaces(): + st = (self.selectorText, self._getUsedNamespaces()) + else: + st = self.selectorText + return u"cssutils.css.%s(selectorText=%r)" % ( + self.__class__.__name__, st) + + def __str__(self): + return u"<cssutils.css.%s object selectorText=%r specificity=%r _namespaces=%r at 0x%x>" % ( + self.__class__.__name__, self.selectorText, self.specificity, + self._getUsedNamespaces(), id(self)) + + def _getUsedUris(self): + "returns list of actually used URIs in this Selector" + uris = set() + for item in self.seq: + type_, val = item.type, item.value + if type_.endswith(u'-selector') or type_ == u'universal' and \ + type(val) == tuple and val[0] not in (None, u'*'): + uris.add(val[0]) + return uris + + def _getUsedNamespaces(self): + "returns actually used namespaces only" + useduris = self._getUsedUris() + namespaces = _SimpleNamespaces(log=self._log) + for p, uri in self._namespaces.items(): + if uri in useduris: + namespaces[p] = uri + return namespaces diff --git a/src/cssutils/css/selectorlist.py b/src/cssutils/css/selectorlist.py new file mode 100644 index 0000000000..4fe21b1110 --- /dev/null +++ b/src/cssutils/css/selectorlist.py @@ -0,0 +1,249 @@ +"""SelectorList is a list of CSS Selector objects. + +TODO + - remove duplicate Selectors. -> CSSOM canonicalize + + - ??? CSS2 gives a special meaning to the comma (,) in selectors. + However, since it is not known if the comma may acquire other + meanings in future versions of CSS, the whole statement should be + ignored if there is an error anywhere in the selector, even though + the rest of the selector may look reasonable in CSS2. + + Illegal example(s): + + For example, since the "&" is not a valid token in a CSS2 selector, + a CSS2 user agent must ignore the whole second line, and not set + the color of H3 to red: +""" +__all__ = ['SelectorList'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: selectorlist.py 1174 2008-03-20 17:43:07Z cthedot $' + +import xml.dom +import cssutils +from selector import Selector + +class SelectorList(cssutils.util.Base, cssutils.util.ListSeq): + """ + (cssutils) a list of Selectors of a CSSStyleRule + + Properties + ========== + length: of type unsigned long, readonly + The number of Selector elements in the list. + parentRule: of type CSSRule, readonly + The CSS rule that contains this selector list or None if this + list is not attached to a CSSRule. + selectorText: of type DOMString + The textual representation of the selector for the rule set. The + implementation may have stripped out insignificant whitespace while + parsing the selector. + seq: (internal use!) + A list of Selector objects + wellformed + if this selectorlist is wellformed regarding the Selector spec + """ + def __init__(self, selectorText=None, parentRule=None, + readonly=False): + """ + initializes SelectorList with optional selectorText + + :Parameters: + selectorText + parsable list of Selectors + parentRule + the parent CSSRule if available + """ + super(SelectorList, self).__init__() + + self._parentRule = parentRule + + if selectorText: + self.selectorText = selectorText + + self._readonly = readonly + + def __prepareset(self, newSelector, namespaces=None): + "used by appendSelector and __setitem__" + if not namespaces: + namespaces = {} + self._checkReadonly() + if not isinstance(newSelector, Selector): + newSelector = Selector((newSelector, namespaces), + parentList=self) + if newSelector.wellformed: + newSelector._parent = self # maybe set twice but must be! + return newSelector + + def __setitem__(self, index, newSelector): + """ + overwrites ListSeq.__setitem__ + + Any duplicate Selectors are **not** removed. + """ + newSelector = self.__prepareset(newSelector) + if newSelector: + self.seq[index] = newSelector + + def append(self, newSelector): + "same as appendSelector(newSelector)" + self.appendSelector(newSelector) + + length = property(lambda self: len(self), + doc="The number of Selector elements in the list.") + + + def __getNamespaces(self): + "uses children namespaces if not attached to a sheet, else the sheet's ones" + try: + return self.parentRule.parentStyleSheet.namespaces + except AttributeError: + namespaces = {} + for selector in self.seq: + namespaces.update(selector._namespaces) + return namespaces + + _namespaces = property(__getNamespaces, doc="""if this SelectorList is + attached to a CSSStyleSheet the namespaces of that sheet are mirrored + here. While the SelectorList (or parentRule(s) are + not attached the namespaces of all children Selectors are used.""") + + parentRule = property(lambda self: self._parentRule, + doc="(DOM) The CSS rule that contains this SelectorList or\ + None if this SelectorList is not attached to a CSSRule.") + + def _getSelectorText(self): + "returns serialized format" + return cssutils.ser.do_css_SelectorList(self) + + def _setSelectorText(self, selectorText): + """ + :param selectorText: + comma-separated list of selectors or a tuple of + (selectorText, dict-of-namespaces) + :Exceptions: + - `NAMESPACE_ERR`: (Selector) + Raised if the specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (self) + Raised if the specified CSS string value has a syntax error + and is unparsable. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this rule is readonly. + """ + self._checkReadonly() + + # might be (selectorText, namespaces) + selectorText, namespaces = self._splitNamespacesOff(selectorText) + try: + # use parent's only if available + namespaces = self.parentRule.parentStyleSheet.namespaces + except AttributeError: + pass + + wellformed = True + tokenizer = self._tokenize2(selectorText) + newseq = [] + + expected = True + while True: + # find all upto and including next ",", EOF or nothing + selectortokens = self._tokensupto2(tokenizer, listseponly=True) + if selectortokens: + if self._tokenvalue(selectortokens[-1]) == ',': + expected = selectortokens.pop() + else: + expected = None + + selector = Selector((selectortokens, namespaces), + parentList=self) + if selector.wellformed: + newseq.append(selector) + else: + wellformed = False + self._log.error(u'SelectorList: Invalid Selector: %s' % + self._valuestr(selectortokens)) + else: + break + + # post condition + if u',' == expected: + wellformed = False + self._log.error(u'SelectorList: Cannot end with ",": %r' % + self._valuestr(selectorText)) + elif expected: + wellformed = False + self._log.error(u'SelectorList: Unknown Syntax: %r' % + self._valuestr(selectorText)) + if wellformed: + self.seq = newseq +# for selector in newseq: +# self.appendSelector(selector) + + selectorText = property(_getSelectorText, _setSelectorText, + doc="""(cssutils) The textual representation of the selector for + a rule set.""") + + wellformed = property(lambda self: bool(len(self.seq))) + + def appendSelector(self, newSelector): + """ + Append newSelector (a string will be converted to a new + Selector). + + :param newSelector: + comma-separated list of selectors or a tuple of + (selectorText, dict-of-namespaces) + :returns: New Selector or None if newSelector is not wellformed. + :Exceptions: + - `NAMESPACE_ERR`: (self) + Raised if the specified selector uses an unknown namespace + prefix. + - `SYNTAX_ERR`: (self) + Raised if the specified CSS string value has a syntax error + and is unparsable. + - `NO_MODIFICATION_ALLOWED_ERR`: (self) + Raised if this rule is readonly. + """ + self._checkReadonly() + + # might be (selectorText, namespaces) + newSelector, namespaces = self._splitNamespacesOff(newSelector) + try: + # use parent's only if available + namespaces = self.parentRule.parentStyleSheet.namespaces + except AttributeError: + # use already present namespaces plus new given ones + _namespaces = self._namespaces + _namespaces.update(namespaces) + namespaces = _namespaces + + newSelector = self.__prepareset(newSelector, namespaces) + if newSelector: + seq = self.seq[:] + del self.seq[:] + for s in seq: + if s.selectorText != newSelector.selectorText: + self.seq.append(s) + self.seq.append(newSelector) + return newSelector + + def __repr__(self): + if self._namespaces: + st = (self.selectorText, self._namespaces) + else: + st = self.selectorText + return "cssutils.css.%s(selectorText=%r)" % ( + self.__class__.__name__, st) + + def __str__(self): + return "<cssutils.css.%s object selectorText=%r _namespaces=%r at 0x%x>" % ( + self.__class__.__name__, self.selectorText, self._namespaces, + id(self)) + + def _getUsedUris(self): + "used by CSSStyleSheet to check if @namespace rules are needed" + uris = set() + for s in self: + uris.update(s._getUsedUris()) + return uris diff --git a/src/cssutils/css2productions.py b/src/cssutils/css2productions.py new file mode 100644 index 0000000000..a836df3f93 --- /dev/null +++ b/src/cssutils/css2productions.py @@ -0,0 +1,131 @@ +"""productions for CSS 2.1 + +CSS2_1_MACROS and CSS2_1_PRODUCTIONS are from both +http://www.w3.org/TR/CSS21/grammar.html and +http://www.w3.org/TR/css3-syntax/#grammar0 + + +""" +__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: css2productions.py 1394 2008-07-27 13:29:22Z cthedot $' + +# option case-insensitive +MACROS = { + 'h': r'[0-9a-f]', + #'nonascii': r'[\200-\377]', + 'nonascii': r'[^\0-\177]', # CSS3 + 'unicode': r'\\{h}{1,6}(\r\n|[ \t\r\n\f])?', + + 'escape': r'{unicode}|\\[^\r\n\f0-9a-f]', + 'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}', + 'nmchar': r'[_a-zA-Z0-9-]|{nonascii}|{escape}', + 'string1': r'\"([^\n\r\f\\"]|\\{nl}|{escape})*\"', + 'string2': r"\'([^\n\r\f\\']|\\{nl}|{escape})*\'", + 'invalid1': r'\"([^\n\r\f\\"]|\\{nl}|{escape})*', + 'invalid2': r"\'([^\n\r\f\\']|\\{nl}|{escape})*", + 'comment': r'\/\*[^*]*\*+([^/*][^*]*\*+)*\/', + # CSS list 080725 19:43 + # \/\*([^*\\]|{escape})*\*+(([^/*\\]|{escape})[^*]*\*+)*\/ + + 'ident': r'[-]?{nmstart}{nmchar}*', + 'name': r'{nmchar}+', + # CHANGED TO SPEC: added "-?" + 'num': r'-?[0-9]*\.[0-9]+|[0-9]+', + 'string': r'{string1}|{string2}', + 'invalid': r'{invalid1}|{invalid2}', + 'url': r'([!#$%&*-~]|{nonascii}|{escape})*', + 's': r'[ \t\r\n\f]+', + 'w': r'{s}?', + 'nl': r'\n|\r\n|\r|\f', + 'range': r'\?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|{h})))))', + + 'A': r'a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])?', + 'C': r'c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])?', + 'D': r'd|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?', + 'E': r'e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?', + 'F': r'f|\\0{0,4}(46|66)(\r\n|[ \t\r\n\f])?', + 'G': r'g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g', + 'H': r'h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h', + 'I': r'i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i', + 'K': r'k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k', + 'M': r'm|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m', + 'N': r'n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n', + 'O': r'o|\\0{0,4}(51|71)(\r\n|[ \t\r\n\f])?|\\o', + 'P': r'p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p', + 'R': r'r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r', + 'S': r's|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s', + 'T': r't|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t', + 'X': r'x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x', + 'Z': r'z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z', + } + +PRODUCTIONS = [ + ('URI', r'url\({w}{string}{w}\)'), #"url("{w}{string}{w}")" {return URI;} + ('URI', r'url\({w}{url}{w}\)'), #"url("{w}{url}{w}")" {return URI;} + ('FUNCTION', r'{ident}\('), #{ident}"(" {return FUNCTION;} + + ('IMPORT_SYM', r'@{I}{M}{P}{O}{R}{T}'), #"@import" {return IMPORT_SYM;} + ('PAGE_SYM', r'@{P}{A}{G}{E}'), #"@page" {return PAGE_SYM;} + ('MEDIA_SYM', r'@{M}{E}{D}{I}{A}'), #"@media" {return MEDIA_SYM;} + ('FONT_FACE_SYM', r'@{F}{O}{N}{T}\-{F}{A}{C}{E}'), #"@font-face" {return FONT_FACE_SYM;} + + # CHANGED TO SPEC: only @charset + ('CHARSET_SYM', r'@charset '), #"@charset " {return CHARSET_SYM;} + + ('NAMESPACE_SYM', r'@{N}{A}{M}{E}{S}{P}{A}{C}{E}'), #"@namespace" {return NAMESPACE_SYM;} + + # CHANGED TO SPEC: ATKEYWORD + ('ATKEYWORD', r'\@{ident}'), + + ('IDENT', r'{ident}'), #{ident} {return IDENT;} + ('STRING', r'{string}'), #{string} {return STRING;} + ('INVALID', r'{invalid}'), # {return INVALID; /* unclosed string */} + ('HASH', r'\#{name}'), #"#"{name} {return HASH;} + ('PERCENTAGE', r'{num}%'), #{num}% {return PERCENTAGE;} + ('LENGTH', r'{num}{E}{M}'), #{num}em {return EMS;} + ('LENGTH', r'{num}{E}{X}'), #{num}ex {return EXS;} + ('LENGTH', r'{num}{P}{X}'), #{num}px {return LENGTH;} + ('LENGTH', r'{num}{C}{M}'), #{num}cm {return LENGTH;} + ('LENGTH', r'{num}{M}{M}'), #{num}mm {return LENGTH;} + ('LENGTH', r'{num}{I}{N}'), #{num}in {return LENGTH;} + ('LENGTH', r'{num}{P}{T}'), #{num}pt {return LENGTH;} + ('LENGTH', r'{num}{P}{C}'), #{num}pc {return LENGTH;} + ('ANGLE', r'{num}{D}{E}{G}'), #{num}deg {return ANGLE;} + ('ANGLE', r'{num}{R}{A}{D}'), #{num}rad {return ANGLE;} + ('ANGLE', r'{num}{G}{R}{A}{D}'), #{num}grad {return ANGLE;} + ('TIME', r'{num}{M}{S}'), #{num}ms {return TIME;} + ('TIME', r'{num}{S}'), #{num}s {return TIME;} + ('FREQ', r'{num}{H}{Z}'), #{num}Hz {return FREQ;} + ('FREQ', r'{num}{K}{H}{Z}'), #{num}kHz {return FREQ;} + ('DIMEN', r'{num}{ident}'), #{num}{ident} {return DIMEN;} + ('NUMBER', r'{num}'), #{num} {return NUMBER;} + #('UNICODERANGE', r'U\+{range}'), #U\+{range} {return UNICODERANGE;} + #('UNICODERANGE', r'U\+{h}{1,6}-{h}{1,6}'), #U\+{h}{1,6}-{h}{1,6} {return UNICODERANGE;} + # --- CSS3 --- + ('UNICODE-RANGE', r'[0-9A-F?]{1,6}(\-[0-9A-F]{1,6})?'), + ('CDO', r'\<\!\-\-'), #"<!--" {return CDO;} + ('CDC', r'\-\-\>'), #"-->" {return CDC;} + ('S', r'{s}'),# {return S;} + + # \/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */ + # {s}+\/\*[^*]*\*+([^/*][^*]*\*+)*\/ {unput(' '); /*replace by space*/} + + ('INCLUDES', r'\~\='), #"~=" {return INCLUDES;} + ('DASHMATCH', r'\|\='), #"|=" {return DASHMATCH;} + ('LBRACE', r'\{'), #{w}"{" {return LBRACE;} + ('PLUS', r'\+'), #{w}"+" {return PLUS;} + ('GREATER', r'\>'), #{w}">" {return GREATER;} + ('COMMA', r'\,'), #{w}"," {return COMMA;} + ('IMPORTANT_SYM', r'\!({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T}'), #"!{w}important" {return IMPORTANT_SYM;} + ('COMMENT', '\/\*[^*]*\*+([^/][^*]*\*+)*\/'), # /* ignore comments */ + ('CLASS', r'\.'), #. {return *yytext;} + + # --- CSS3! --- + ('CHAR', r'[^"\']'), + ] + +class CSSProductions(object): + pass +for i, t in enumerate(PRODUCTIONS): + setattr(CSSProductions, t[0].replace('-', '_'), t[0]) \ No newline at end of file diff --git a/src/cssutils/css3productions.py b/src/cssutils/css3productions.py new file mode 100644 index 0000000000..bfd02fa8ac --- /dev/null +++ b/src/cssutils/css3productions.py @@ -0,0 +1,62 @@ +"""productions for CSS 3 + +CSS3_MACROS and CSS3_PRODUCTIONS are from http://www.w3.org/TR/css3-syntax +""" +__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: css3productions.py 1116 2008-03-05 13:52:23Z cthedot $' + +# a complete list of css3 macros +MACROS = { + 'ident': r'[-]?{nmstart}{nmchar}*', + 'name': r'{nmchar}+', + 'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}', + 'nonascii': r'[^\0-\177]', + 'unicode': r'\\[0-9a-f]{1,6}{wc}?', + 'escape': r'{unicode}|\\[ -~\200-\777]', + # 'escape': r'{unicode}|\\[ -~\200-\4177777]', + 'nmchar': r'[-_a-zA-Z0-9]|{nonascii}|{escape}', + + # CHANGED TO SPEC: added "-?" + 'num': r'-?[0-9]*\.[0-9]+|[0-9]+', #r'[-]?\d+|[-]?\d*\.\d+', + 'string': r'''\'({stringchar}|\")*\'|\"({stringchar}|\')*\"''', + 'stringchar': r'{urlchar}| |\\{nl}', + 'urlchar': r'[\x09\x21\x23-\x26\x27-\x7E]|{nonascii}|{escape}', + # what if \r\n, \n matches first? + 'nl': r'\n|\r\n|\r|\f', + 'w': r'{wc}*', + 'wc': r'\t|\r|\n|\f|\x20' + } + +# The following productions are the complete list of tokens in CSS3, the productions are **ordered**: +PRODUCTIONS = [ + ('BOM', r'\xFEFF'), + ('URI', r'url\({w}({string}|{urlchar}*){w}\)'), + ('FUNCTION', r'{ident}\('), + ('ATKEYWORD', r'\@{ident}'), + ('IDENT', r'{ident}'), + ('STRING', r'{string}'), + ('HASH', r'\#{name}'), + ('PERCENTAGE', r'{num}\%'), + ('DIMENSION', r'{num}{ident}'), + ('NUMBER', r'{num}'), + #??? + ('UNICODE-RANGE', ur'[0-9A-F?]{1,6}(\-[0-9A-F]{1,6})?'), + ('CDO', r'\<\!\-\-'), + ('CDC', r'\-\-\>'), + ('S', r'{wc}+'), + ('INCLUDES', '\~\='), + ('DASHMATCH', r'\|\='), + ('PREFIXMATCH', r'\^\='), + ('SUFFIXMATCH', r'\$\='), + ('SUBSTRINGMATCH', r'\*\='), + ('COMMENT', r'\/\*[^*]*\*+([^/][^*]*\*+)*\/'), + ('CHAR', r'[^"\']'), + ] + +class CSSProductions(object): + "has attributes for all PRODUCTIONS" + pass + +for i, t in enumerate(PRODUCTIONS): + setattr(CSSProductions, t[0].replace('-', '_'), t[0]) diff --git a/src/cssutils/cssproductions.py b/src/cssutils/cssproductions.py new file mode 100644 index 0000000000..63f856442b --- /dev/null +++ b/src/cssutils/cssproductions.py @@ -0,0 +1,121 @@ +"""productions for cssutils based on a mix of CSS 2.1 and CSS 3 Syntax +productions + +- http://www.w3.org/TR/css3-syntax +- http://www.w3.org/TR/css3-syntax/#grammar0 + +open issues + - numbers contain "-" if present + - HASH: #aaa is, #000 is not anymore, + CSS2.1: 'nmchar': r'[_a-z0-9-]|{nonascii}|{escape}', + CSS3: 'nmchar': r'[_a-z-]|{nonascii}|{escape}', +""" +__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssproductions.py 1378 2008-07-15 20:02:19Z cthedot $' + +# a complete list of css3 macros +MACROS = { + 'ident': r'[-]?{nmstart}{nmchar}*', + 'name': r'{nmchar}+', + 'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}', + 'nonascii': r'[^\0-\177]', + 'unicode': r'\\[0-9a-f]{1,6}(?:{nl}|{wc})?', + 'escape': r'{unicode}|\\[ -~\200-\777]', + # 'escape': r'{unicode}|\\[ -~\200-\4177777]', + 'nmchar': r'[-_a-zA-Z0-9]|{nonascii}|{escape}', + + 'num': r'[0-9]*\.[0-9]+|[0-9]+', #r'[-]?\d+|[-]?\d*\.\d+', + 'string': r"""\'({stringesc1}|{stringchar}|")*\'""" + "|" + '''\"({stringesc2}|{stringchar}|')*\"''', + # seems an error in CSS 3 but is allowed in CSS 2.1 + 'stringesc1' : r"\\'", + 'stringesc2' : r'\\"', + + 'stringchar': r'{urlchar}| |\\{nl}', + + # urlchar ::= [#x9#x21#x23-#x26#x27-#x7E] | nonascii | escape + # 0x27 is "'" which should not be in here..., should ) be in here??? + 'urlchar': r'[\x09\x21\x23-\x26\x28-\x7E]|{nonascii}|{escape}', + + # from CSS2.1 + 'invalid': r'{invalid1}|{invalid2}', + 'invalid1': r'\"([^\n\r\f\\"]|\\{nl}|{escape})*', + 'invalid2': r"\'([^\n\r\f\\']|\\{nl}|{escape})*", + + # \r\n should be counted as one char see unicode above + 'nl': r'\n|\r\n|\r|\f', + 'w': r'{wc}*', + 'wc': r'\t|\r|\n|\f|\x20', + + 'comment': r'\/\*[^*]*\*+([^/][^*]*\*+)*\/', + + 'A': r'A|a|\\0{0,4}(?:41|61)(?:\r\n|[ \t\r\n\f])?', + 'C': r'C|c|\\0{0,4}(?:43|63)(?:\r\n|[ \t\r\n\f])?', + 'D': r'D|d|\\0{0,4}(?:44|64)(?:\r\n|[ \t\r\n\f])?', + 'E': r'E|e|\\0{0,4}(?:45|65)(?:\r\n|[ \t\r\n\f])?', + 'F': r'F|f|\\0{0,4}(?:46|66)(?:\r\n|[ \t\r\n\f])?', + 'G': r'G|g|\\0{0,4}(?:47|67)(?:\r\n|[ \t\r\n\f])?|\\G|\\g', + 'H': r'H|h|\\0{0,4}(?:48|68)(?:\r\n|[ \t\r\n\f])?|\\H|\\h', + 'I': r'I|i|\\0{0,4}(?:49|69)(?:\r\n|[ \t\r\n\f])?|\\I|\\i', + 'K': r'K|k|\\0{0,4}(?:4b|6b)(?:\r\n|[ \t\r\n\f])?|\\K|\\k', + 'L': r'L|l|\\0{0,4}(?:4c|6c)(?:\r\n|[ \t\r\n\f])?|\\L|\\l', + 'M': r'M|m|\\0{0,4}(?:4d|6d)(?:\r\n|[ \t\r\n\f])?|\\M|\\m', + 'N': r'N|n|\\0{0,4}(?:4e|6e)(?:\r\n|[ \t\r\n\f])?|\\N|\\n', + 'O': r'O|o|\\0{0,4}(?:4f|6f)(?:\r\n|[ \t\r\n\f])?|\\O|\\o', + 'P': r'P|p|\\0{0,4}(?:50|70)(?:\r\n|[ \t\r\n\f])?|\\P|\\p', + 'R': r'R|r|\\0{0,4}(?:52|72)(?:\r\n|[ \t\r\n\f])?|\\R|\\r', + 'S': r'S|s|\\0{0,4}(?:53|73)(?:\r\n|[ \t\r\n\f])?|\\S|\\s', + 'T': r'T|t|\\0{0,4}(?:54|74)(?:\r\n|[ \t\r\n\f])?|\\T|\\t', + 'U': r'U|u|\\0{0,4}(?:55|75)(?:\r\n|[ \t\r\n\f])?|\\U|\\u', + 'X': r'X|x|\\0{0,4}(?:58|78)(?:\r\n|[ \t\r\n\f])?|\\X|\\x', + 'Z': r'Z|z|\\0{0,4}(?:5a|7a)(?:\r\n|[ \t\r\n\f])?|\\Z|\\z', + } + +# The following productions are the complete list of tokens +# used by cssutils, a mix of CSS3 and some CSS2.1 productions. +# The productions are **ordered**: +PRODUCTIONS = [ + ('BOM', r'\xFEFF'), # will only be checked at beginning of CSS + + ('S', r'{wc}+'), # 1st in list of general productions + ('URI', r'{U}{R}{L}\({w}({string}|{urlchar}*){w}\)'), + ('FUNCTION', r'{ident}\('), + ('IDENT', r'{ident}'), + ('STRING', r'{string}'), + ('INVALID', r'{invalid}'), # from CSS2.1 + ('HASH', r'\#{name}'), + ('PERCENTAGE', r'{num}\%'), + ('DIMENSION', r'{num}{ident}'), + ('NUMBER', r'{num}'), + # valid ony at start so not checked everytime + #('CHARSET_SYM', r'@charset '), # from Errata includes ending space! + ('ATKEYWORD', r'@{ident}'), # other keywords are done in the tokenizer + #('UNICODE-RANGE', r'[0-9A-F?]{1,6}(\-[0-9A-F]{1,6})?'), #??? + ('CDO', r'\<\!\-\-'), + ('CDC', r'\-\-\>'), + ('INCLUDES', '\~\='), + ('DASHMATCH', r'\|\='), + ('PREFIXMATCH', r'\^\='), + ('SUFFIXMATCH', r'\$\='), + ('SUBSTRINGMATCH', r'\*\='), + # checked specially if fullsheet is parsed + ('COMMENT', r'{comment}'), #r'\/\*[^*]*\*+([^/][^*]*\*+)*\/'), + ('CHAR', r'[^"\']') # MUST always be last + ] + +class CSSProductions(object): + """ + most attributes are set later + """ + EOF = True + # removed from productions as they simply are ATKEYWORD until + # tokenizing + CHARSET_SYM = 'CHARSET_SYM' + FONT_FACE_SYM = 'FONT_FACE_SYM' + MEDIA_SYM = 'MEDIA_SYM' + IMPORT_SYM = 'IMPORT_SYM' + NAMESPACE_SYM = 'NAMESPACE_SYM' + PAGE_SYM = 'PAGE_SYM' + +for i, t in enumerate(PRODUCTIONS): + setattr(CSSProductions, t[0].replace('-', '_'), t[0]) diff --git a/src/cssutils/errorhandler.py b/src/cssutils/errorhandler.py new file mode 100644 index 0000000000..89a8c7bca9 --- /dev/null +++ b/src/cssutils/errorhandler.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +"""cssutils ErrorHandler + +ErrorHandler + used as log with usual levels (debug, info, warn, error) + + if instanciated with ``raiseExceptions=True`` raises exeptions instead + of logging + +log + defaults to instance of ErrorHandler for any kind of log message from + lexerm, parser etc. + + - raiseExceptions = [False, True] + - setloglevel(loglevel) +""" +__all__ = ['ErrorHandler'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: errorhandler.py 1361 2008-07-13 18:12:40Z cthedot $' + +import logging +import urllib2 +import xml.dom +from helper import Deprecated + +class _ErrorHandler(object): + """ + handles all errors and log messages + """ + def __init__(self, log, defaultloglevel=logging.INFO, + raiseExceptions=True): + """ + inits log if none given + + log + for parse messages, default logs to sys.stderr + defaultloglevel + if none give this is logging.DEBUG + raiseExceptions + - True: Errors will be raised e.g. during building + - False: Errors will be written to the log, this is the + default behaviour when parsing + """ + if log: + self._log = log + else: + import sys + self._log = logging.getLogger('CSSUTILS') + hdlr = logging.StreamHandler(sys.stderr) + formatter = logging.Formatter('%(levelname)s\t%(message)s') + hdlr.setFormatter(formatter) + self._log.addHandler(hdlr) + self._log.setLevel(defaultloglevel) + + self.raiseExceptions = raiseExceptions + + def __getattr__(self, name): + "use self._log items" + calls = ('debug', 'info', 'warn', 'error', 'critical', 'fatal') + other = ('setLevel', 'getEffectiveLevel', 'addHandler', 'removeHandler') + + if name in calls: + self._logcall = getattr(self._log, name) + return self.__handle + elif name in other: + return getattr(self._log, name) + else: + raise AttributeError( + '(errorhandler) No Attribute %r found' % name) + + def __handle(self, msg=u'', token=None, error=xml.dom.SyntaxErr, + neverraise=False, args=None): + """ + handles all calls + logs or raises exception + """ + if token: + if isinstance(token, tuple): + msg = u'%s [%s:%s: %s]' % ( + msg, token[2], token[3], token[1]) + else: + msg = u'%s [%s:%s: %s]' % ( + msg, token.line, token.col, token.value) + + if error and self.raiseExceptions and not neverraise: + if isinstance(error, urllib2.HTTPError) or isinstance(error, urllib2.URLError): + raise error + else: + raise error(msg) + else: + self._logcall(msg) + + def setLog(self, log): + """set log of errorhandler's log""" + self._log = log + + @Deprecated('Use setLog() instead.') + def setlog(self, log): + self.setLog(log) + + @Deprecated('Use setLevel() instead.') + def setloglevel(self, level): + self.setLevel(level) + + +class ErrorHandler(_ErrorHandler): + "Singleton, see _ErrorHandler" + instance = None + + def __init__(self, + log=None, defaultloglevel=logging.INFO, raiseExceptions=True): + + if ErrorHandler.instance is None: + ErrorHandler.instance = _ErrorHandler(log=log, + defaultloglevel=defaultloglevel, + raiseExceptions=raiseExceptions) + self.__dict__ = ErrorHandler.instance.__dict__ diff --git a/src/cssutils/helper.py b/src/cssutils/helper.py new file mode 100644 index 0000000000..9dafd9437c --- /dev/null +++ b/src/cssutils/helper.py @@ -0,0 +1,51 @@ +"""cssutils helper +""" +__all__ = ['Deprecated', 'normalize'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: errorhandler.py 1234 2008-05-22 20:26:12Z cthedot $' + +import re + +class Deprecated(object): + """This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used. + + It accepts a single paramter ``msg`` which is shown with the warning. + It should contain information which function or method to use instead. + """ + def __init__(self, msg): + self.msg = msg + + def __call__(self, func): + def newFunc(*args, **kwargs): + import warnings + warnings.warn("Call to deprecated method %r. %s" % + (func.__name__, self.msg), + category=DeprecationWarning, + stacklevel=2) + return func(*args, **kwargs) + newFunc.__name__ = func.__name__ + newFunc.__doc__ = func.__doc__ + newFunc.__dict__.update(func.__dict__) + return newFunc + +# simple escapes, all non unicodes +_simpleescapes = re.compile(ur'(\\[^0-9a-fA-F])').sub + +def normalize(x): + """ + normalizes x, namely: + + - remove any \ before non unicode sequences (0-9a-zA-Z) so for + x=="c\olor\" return "color" (unicode escape sequences should have + been resolved by the tokenizer already) + - lowercase + """ + if x: + def removeescape(matchobj): + return matchobj.group(0)[1:] + x = _simpleescapes(removeescape, x) + return x.lower() + else: + return x \ No newline at end of file diff --git a/src/cssutils/parse.py b/src/cssutils/parse.py new file mode 100644 index 0000000000..4aa0bd831e --- /dev/null +++ b/src/cssutils/parse.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +"""a validating CSSParser +""" +__all__ = ['CSSParser'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: parse.py 1418 2008-08-09 19:27:50Z cthedot $' + +import codecs +import os +import urllib +from helper import Deprecated +import tokenize2 +import cssutils + +class CSSParser(object): + """ + parses a CSS StyleSheet string or file and + returns a DOM Level 2 CSS StyleSheet object + + Usage:: + + parser = CSSParser() + + # optionally + parser.setFetcher(fetcher) + + sheet = parser.parseFile('test1.css', 'ascii') + + print sheet.cssText + """ + def __init__(self, log=None, loglevel=None, raiseExceptions=None, + fetcher=None): + """ + log + logging object + loglevel + logging loglevel + raiseExceptions + if log should simply log (default) or raise errors during + parsing. Later while working with the resulting sheets + the setting used in cssutils.log.raiseExeptions is used + fetcher + see ``setFetchUrl(fetcher)`` + """ + if log is not None: + cssutils.log.setLog(log) + if loglevel is not None: + cssutils.log.setLevel(loglevel) + + # remember global setting + self.__globalRaising = cssutils.log.raiseExceptions + if raiseExceptions: + self.__parseRaising = raiseExceptions + else: + # DEFAULT during parse + self.__parseRaising = False + + self.__tokenizer = tokenize2.Tokenizer() + self.setFetcher(fetcher) + + def __parseSetting(self, parse): + """during parse exceptions may be handled differently depending on + init parameter ``raiseExceptions`` + """ + if parse: + cssutils.log.raiseExceptions = self.__parseRaising + else: + cssutils.log.raiseExceptions = self.__globalRaising + + def parseString(self, cssText, encoding=None, href=None, media=None, + title=None): + """Return parsed CSSStyleSheet from given string cssText. + Raises errors during retrieving (e.g. UnicodeDecodeError). + + cssText + CSS string to parse + encoding + If ``None`` the encoding will be read from BOM or an @charset + rule or defaults to UTF-8. + If given overrides any found encoding including the ones for + imported sheets. + It also will be used to decode ``cssText`` if given as a (byte) + string. + href + The href attribute to assign to the parsed style sheet. + Used to resolve other urls in the parsed sheet like @import hrefs + media + The media attribute to assign to the parsed style sheet + (may be a MediaList, list or a string) + title + The title attribute to assign to the parsed style sheet + """ + self.__parseSetting(True) + if isinstance(cssText, str): + cssText = codecs.getdecoder('css')(cssText, encoding=encoding)[0] + + sheet = cssutils.css.CSSStyleSheet(href=href, + media=cssutils.stylesheets.MediaList(media), + title=title) + sheet._setFetcher(self.__fetcher) + # tokenizing this ways closes open constructs and adds EOF + sheet._setCssTextWithEncodingOverride(self.__tokenizer.tokenize(cssText, + fullsheet=True), + encodingOverride=encoding) + self.__parseSetting(False) + return sheet + + def parseFile(self, filename, encoding=None, + href=None, media=None, title=None): + """Retrieve and return a CSSStyleSheet from given filename. + Raises errors during retrieving (e.g. IOError). + + filename + of the CSS file to parse, if no ``href`` is given filename is + converted to a (file:) URL and set as ``href`` of resulting + stylesheet. + If href is given it is set as ``sheet.href``. Either way + ``sheet.href`` is used to resolve e.g. stylesheet imports via + @import rules. + encoding + Value ``None`` defaults to encoding detection via BOM or an + @charset rule. + Other values override detected encoding for the sheet at + ``filename`` including any imported sheets. + + for other parameters see ``parseString`` + """ + if not href: + # prepend // for file URL, urllib does not do this? + href = u'file:' + urllib.pathname2url(os.path.abspath(filename)) + + return self.parseString(open(filename, 'rb').read(), + encoding=encoding, # read returns a str + href=href, media=media, title=title) + + def parseUrl(self, href, encoding=None, media=None, title=None): + """Retrieve and return a CSSStyleSheet from given href (an URL). + In case of any errors while reading the URL returns None. + + href + URL of the CSS file to parse, will also be set as ``href`` of + resulting stylesheet + encoding + Value ``None`` defaults to encoding detection via HTTP, BOM or an + @charset rule. + A value overrides detected encoding for the sheet at ``href`` + including any imported sheets. + + for other parameters see ``parseString`` + """ + encoding, enctype, text = cssutils.util._readUrl(href, + overrideEncoding=encoding) + if enctype == 5: + # do not used if defaulting to UTF-8 + encoding = None + + if text is not None: + return self.parseString(text, encoding=encoding, + href=href, media=media, title=title) + + def setFetcher(self, fetcher=None): + """Replace the default URL fetch function with a custom one. + The fetcher function gets a single parameter + + ``url`` + the URL to read + + and returns ``(encoding, content)`` where ``encoding`` is the HTTP + charset normally given via the Content-Type header (which may simply + omit the charset) and ``content`` being the (byte) string content. + The Mimetype should be 'text/css' but this has to be checked by the + fetcher itself (the default fetcher emits a warning if encountering + a different mimetype). + + Calling ``setFetcher`` with ``fetcher=None`` resets cssutils + to use its default function. + """ + self.__fetcher = fetcher + + @Deprecated('Use cssutils.CSSParser().parseFile() instead.') + def parse(self, filename, encoding=None, + href=None, media=None, title=None): + self.parseFile(filename, encoding, href, media, title) diff --git a/src/cssutils/prodparser.py b/src/cssutils/prodparser.py new file mode 100644 index 0000000000..bf2f32484c --- /dev/null +++ b/src/cssutils/prodparser.py @@ -0,0 +1,402 @@ +# -*- coding: utf-8 -*- +"""Productions parser used by css and stylesheets classes to parse +test into a cssutils.util.Seq and at the same time retrieving +additional specific cssutils.util.Item objects for later use. + +TODO: + - ProdsParser + - handle EOF or STOP? + - handle unknown @rules + - handle S: maybe save to Seq? parameterized? + - store['_raw']: always? + + - Sequence: + - opt first(), naive impl for now + +""" +__all__ = ['ProdParser', 'Sequence', 'Choice', 'Prod', 'PreDef'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: parse.py 1418 2008-08-09 19:27:50Z cthedot $' + +import cssutils + + +class ParseError(Exception): + """Base Exception class for ProdParser (used internally).""" + pass + +class Exhausted(ParseError): + """Raised if Sequence or Choice is done.""" + pass + +class NoMatch(ParseError): + """Raised if Sequence or Choice do not match.""" + pass + +class MissingToken(ParseError): + """Raised if Sequence or Choice are not exhausted.""" + pass + + +class Choice(object): + """A Choice of productions (Sequence or single Prod).""" + def __init__(self, prods): + """ + prods + Prod or Sequence objects + """ + self._prods = prods + self._exhausted = False + + def nextProd(self, token): + """ + Return: + + - next matching Prod or Sequence + - raises ParseError if nothing matches + - raises Exhausted if choice already done + + ``token`` may be None but this occurs when no tokens left.""" + if not self._exhausted: + for x in self._prods: + if isinstance(x, Prod): + test = x + else: + # nested Sequence matches if 1st prod matches + test = x.first() + try: + if test.matches(token): + self._exhausted = True + return x + except ParseError, e: + # do not raise if other my match + continue + else: + # None matched + raise ParseError(u'No match in choice') + else: + raise Exhausted(u'Extra token') + + +class Sequence(object): + """A Sequence of productions (Choice or single Prod).""" + def __init__(self, prods, minmax=None): + """ + prods + Prod or Sequence objects + minmax = lambda: (1, 1) + callback returning number of times this sequence may run + """ + self._prods = prods + if not minmax: + minmax = lambda: (1, 1) + self._min, self._max = minmax() + + self._number = len(self._prods) + self._round = 1 # 1 based! + self._pos = 0 + + def first(self): + """Return 1st element of Sequence, used by Choice""" + # TODO: current impl first only if 1st if an prod! + for prod in self._prods: + if not prod.optional: + return prod + + def _currentName(self): + """Return current element of Sequence, used by name""" + # TODO: current impl first only if 1st if an prod! + for prod in self._prods[self._pos:]: + if not prod.optional: + return prod.name + else: + return 'Unknown' + + name = property(_currentName, doc='Used for Error reporting') + + def nextProd(self, token): + """Return + + - next matching Prod or Choice + - raises ParseError if nothing matches + - raises Exhausted if sequence already done + """ + while self._pos < self._number: + x = self._prods[self._pos] + thisround = self._round + + self._pos += 1 + if self._pos == self._number: + if self._round < self._max: + # new round? + self._pos = 0 + self._round += 1 + + if isinstance(x, Prod): + if not token and (x.optional or thisround > self._min): + # token is None if nothing expected + raise Exhausted() + elif not token and not x.optional: + raise MissingToken(u'Missing token for production %s' + % x.name) + elif x.matches(token): + return x + elif x.optional: + # try next + continue +# elif thisround > self._min: +# # minimum done +# self._round = self._max +# self._pos = self._number +# return None + else: + # should have matched + raise NoMatch(u'No matching production for token') + + else: + # nested Sequence or Choice + return x + + # Sequence is exhausted + if self._round >= self._max: + raise Exhausted(u'Extra token') + + +class Prod(object): + """Single Prod in Sequence or Choice.""" + def __init__(self, name, match, toSeq=None, toStore=None, + optional=False): + """ + name + name used for error reporting + match callback + function called with parameters tokentype and tokenvalue + returning True, False or raising ParseError + toSeq callback (optional) + if given calling toSeq(token) will be appended to seq + else simply seq + toStore (optional) + key to save util.Item to store or callback(store, util.Item) + optional = False + wether Prod is optional or not + """ + self.name = name + self.match = match + self.optional=optional + + def makeToStore(key): + "Return a function used by toStore." + def toStore(store, item): + "Set or append store item." + if key in store: + store[key].append(item) + else: + store[key] = item + return toStore + + if toSeq: + # called: seq.append(toSeq(value)) + self.toSeq = toSeq + else: + self.toSeq = lambda val: val + + if callable(toStore): + self.toStore = toStore + elif toStore: + self.toStore = makeToStore(toStore) + else: + # always set! + self.toStore = None + + def matches(self, token): + """Return if token matches.""" + type_, val, line, col = token + return self.match(type_, val) + + def __repr__(self): + return "<cssutils.prodsparser.%s object name=%r at 0x%x>" % ( + self.__class__.__name__, self.name, id(self)) + + +class ProdParser(object): + """Productions parser.""" + def __init__(self): + self.types = cssutils.cssproductions.CSSProductions + self._log = cssutils.log + self._tokenizer = cssutils.tokenize2.Tokenizer() + + def parse(self, text, name, productions, store=None): + """ + text (or token generator) + to parse, will be tokenized if not a generator yet + + may be: + - a string to be tokenized + - a single token, a tuple + - a tuple of (token, tokensGenerator) + - already tokenized so a tokens generator + + name + used for logging + productions + used to parse tokens + store UPDATED + If a Prod defines ``toStore`` the key defined there + is a key in store to be set or if store[key] is a list + the next Item is appended here. + + TODO: NEEDED? : + Key ``raw`` is always added and holds all unprocessed + values found + + returns + :wellformed: True or False + :seq: a filled cssutils.util.Seq object which is NOT readonly yet + :store: filled keys defined by Prod.toStore + :unusedtokens: token generator containing tokens not used yet + """ + if isinstance(text, basestring): + # to tokenize + tokens = self._tokenizer.tokenize(text) + elif isinstance(text, tuple): + # (token, tokens) or a single token + if len(text) == 2: + # (token, tokens) + def gen(token, tokens): + "new generator appending token and tokens" + yield token + for t in tokens: + yield t + + tokens = (t for t in gen(*text)) + + else: + # single token + tokens = [text] + else: + # already tokenized, assume generator + tokens = text + + # a new seq to append all Items to + seq = cssutils.util.Seq(readonly=False) + + # store for specific values + if not store: + store = {} +# store['_raw'] = [] + + # stack of productions + prods = [productions] + + wellformed = True + for token in tokens: + type_, val, line, col = token +# store['_raw'].append(val) + + # default productions + if type_ == self.types.S: + # always append S? + seq.append(val, type_, line, col) + elif type_ == self.types.COMMENT: + # always append COMMENT + seq.append(val, type_, line, col) +# elif type_ == self.types.ATKEYWORD: +# # @rule +# r = cssutils.css.CSSUnknownRule(cssText=val) +# seq.append(r, type(r), line, col) + elif type_ == self.types.EOF: + # do nothing + pass +# next = 'EOF' + else: + # check prods + try: + while True: + # find next matching production + try: + prod = prods[-1].nextProd(token) + except (NoMatch, Exhausted), e: + # try next + prod = None + + if isinstance(prod, Prod): + break + elif not prod: + if len(prods) > 1: + # nested exhausted, next in parent + prods.pop() + else: + raise Exhausted('Extra token') + else: + # nested Sequence, Choice + prods.append(prod) + + except ParseError, e: + wellformed = False + self._log.error(u'%s: %s: %r' % (name, e, token)) + + else: + # process prod + if prod.toSeq: + seq.append(prod.toSeq(val), type_, line, col) + else: + seq.append(val, type_, line, col) + + if prod.toStore: + prod.toStore(store, seq[-1]) + +# if 'STOP' == next: # EOF? +# # stop here and ignore following tokens +# break + + while True: + # all productions exhausted? + try: + prod = prods[-1].nextProd(token=None) + except Exhausted, e: + prod = None # ok + except (MissingToken, NoMatch), e: + wellformed = False + self._log.error(u'%s: %s' + % (name, e)) + else: + try: + if prod.optional: + # ignore optional ones + continue + except AttributeError: + pass + + if prod: + wellformed = False + self._log.error(u'%s: Missing token for production %r' + % (name, prod.name)) + elif len(prods) > 1: + # nested exhausted, next in parent + prods.pop() + else: + break + + # bool, Seq, None or generator + return wellformed, seq, store, tokens + + +class PreDef(object): + """Predefined Prod definition for use in productions definition + for ProdParser instances. + """ + @staticmethod + def comma(): + "," + return Prod(name=u'comma', match=lambda t, v: v == u',') + + @staticmethod + def funcEnd(): + ")" + return Prod(name=u'end FUNC ")"', match=lambda t, v: v == u')') + + @staticmethod + def unary(): + "+ or -" + return Prod(name=u'unary +-', match=lambda t, v: v in u'+-', + optional=True) diff --git a/src/cssutils/profiles.py b/src/cssutils/profiles.py new file mode 100644 index 0000000000..3d8131f349 --- /dev/null +++ b/src/cssutils/profiles.py @@ -0,0 +1,367 @@ +"""CSS profiles. Predefined are: + +- 'CSS level 2' + +""" +__all__ = ['profiles'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: cssproperties.py 1116 2008-03-05 13:52:23Z cthedot $' + +import cssutils +import re + +""" +Define some regular expression fragments that will be used as +macros within the CSS property value regular expressions. +""" +css2macros = { + 'border-style': 'none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset', + 'border-color': '{color}', + 'border-width': '{length}|thin|medium|thick', + + 'background-color': r'{color}|transparent|inherit', + 'background-image': r'{uri}|none|inherit', + 'background-position': r'({percentage}|{length})(\s*({percentage}|{length}))?|((top|center|bottom)\s*(left|center|right))|((left|center|right)\s*(top|center|bottom))|inherit', + 'background-repeat': r'repeat|repeat-x|repeat-y|no-repeat|inherit', + 'background-attachment': r'scroll|fixed|inherit', + + + 'shape': r'rect\(({w}({length}|auto}){w},){3}{w}({length}|auto){w}\)', + 'counter': r'counter\({w}{identifier}{w}(?:,{w}{list-style-type}{w})?\)', + 'identifier': r'{ident}', + 'family-name': r'{string}|{identifier}', + 'generic-family': r'serif|sans-serif|cursive|fantasy|monospace', + 'absolute-size': r'(x?x-)?(small|large)|medium', + 'relative-size': r'smaller|larger', + 'font-family': r'(({family-name}|{generic-family}){w},{w})*({family-name}|{generic-family})|inherit', + 'font-size': r'{absolute-size}|{relative-size}|{length}|{percentage}|inherit', + 'font-style': r'normal|italic|oblique|inherit', + 'font-variant': r'normal|small-caps|inherit', + 'font-weight': r'normal|bold|bolder|lighter|[1-9]00|inherit', + 'line-height': r'normal|{number}|{length}|{percentage}|inherit', + 'list-style-image': r'{uri}|none|inherit', + 'list-style-position': r'inside|outside|inherit', + 'list-style-type': r'disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman|lower-greek|lower-(latin|alpha)|upper-(latin|alpha)|armenian|georgian|none|inherit', + 'margin-width': r'{length}|{percentage}|auto', + 'outline-color': r'{color}|invert|inherit', + 'outline-style': r'{border-style}|inherit', + 'outline-width': r'{border-width}|inherit', + 'padding-width': r'{length}|{percentage}', + 'specific-voice': r'{identifier}', + 'generic-voice': r'male|female|child', + 'content': r'{string}|{uri}|{counter}|attr\({w}{identifier}{w}\)|open-quote|close-quote|no-open-quote|no-close-quote', + 'border-attrs': r'{border-width}|{border-style}|{border-color}', + 'background-attrs': r'{background-color}|{background-image}|{background-repeat}|{background-attachment}|{background-position}', + 'list-attrs': r'{list-style-type}|{list-style-position}|{list-style-image}', + 'font-attrs': r'{font-style}|{font-variant}|{font-weight}', + 'outline-attrs': r'{outline-color}|{outline-style}|{outline-width}', + 'text-attrs': r'underline|overline|line-through|blink', +} + +""" +Define the regular expressions for validation all CSS values +""" +css2 = { + 'azimuth': r'{angle}|(behind\s+)?(left-side|far-left|left|center-left|center|center-right|right|far-right|right-side)(\s+behind)?|behind|leftwards|rightwards|inherit', + 'background-attachment': r'{background-attachment}', + 'background-color': r'{background-color}', + 'background-image': r'{background-image}', + 'background-position': r'{background-position}', + 'background-repeat': r'{background-repeat}', + # Each piece should only be allowed one time + 'background': r'{background-attrs}(\s+{background-attrs})*|inherit', + 'border-collapse': r'collapse|separate|inherit', + 'border-color': r'({border-color}|transparent)(\s+({border-color}|transparent)){0,3}|inherit', + 'border-spacing': r'{length}(\s+{length})?|inherit', + 'border-style': r'{border-style}(\s+{border-style}){0,3}|inherit', + 'border-top': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-right': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-bottom': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-left': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'border-top-color': r'{border-color}|transparent|inherit', + 'border-right-color': r'{border-color}|transparent|inherit', + 'border-bottom-color': r'{border-color}|transparent|inherit', + 'border-left-color': r'{border-color}|transparent|inherit', + 'border-top-style': r'{border-style}|inherit', + 'border-right-style': r'{border-style}|inherit', + 'border-bottom-style': r'{border-style}|inherit', + 'border-left-style': r'{border-style}|inherit', + 'border-top-width': r'{border-width}|inherit', + 'border-right-width': r'{border-width}|inherit', + 'border-bottom-width': r'{border-width}|inherit', + 'border-left-width': r'{border-width}|inherit', + 'border-width': r'{border-width}(\s+{border-width}){0,3}|inherit', + 'border': r'{border-attrs}(\s+{border-attrs})*|inherit', + 'bottom': r'{length}|{percentage}|auto|inherit', + 'caption-side': r'top|bottom|inherit', + 'clear': r'none|left|right|both|inherit', + 'clip': r'{shape}|auto|inherit', + 'color': r'{color}|inherit', + 'content': r'normal|{content}(\s+{content})*|inherit', + 'counter-increment': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit', + 'counter-reset': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit', + 'cue-after': r'{uri}|none|inherit', + 'cue-before': r'{uri}|none|inherit', + 'cue': r'({uri}|none|inherit){1,2}|inherit', + 'cursor': r'((({uri}{w},{w})*)?(auto|crosshair|default|pointer|move|(e|ne|nw|n|se|sw|s|w)-resize|text|wait|help|progress))|inherit', + 'direction': r'ltr|rtl|inherit', + 'display': r'inline|block|list-item|run-in|inline-block|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|none|inherit', + 'elevation': r'{angle}|below|level|above|higher|lower|inherit', + 'empty-cells': r'show|hide|inherit', + 'float': r'left|right|none|inherit', + 'font-family': r'{font-family}', + 'font-size': r'{font-size}', + 'font-style': r'{font-style}', + 'font-variant': r'{font-variant}', + 'font-weight': r'{font-weight}', + 'font': r'({font-attrs}\s+)*{font-size}({w}/{w}{line-height})?\s+{font-family}|caption|icon|menu|message-box|small-caption|status-bar|inherit', + 'height': r'{length}|{percentage}|auto|inherit', + 'left': r'{length}|{percentage}|auto|inherit', + 'letter-spacing': r'normal|{length}|inherit', + 'line-height': r'{line-height}', + 'list-style-image': r'{list-style-image}', + 'list-style-position': r'{list-style-position}', + 'list-style-type': r'{list-style-type}', + 'list-style': r'{list-attrs}(\s+{list-attrs})*|inherit', + 'margin-right': r'{margin-width}|inherit', + 'margin-left': r'{margin-width}|inherit', + 'margin-top': r'{margin-width}|inherit', + 'margin-bottom': r'{margin-width}|inherit', + 'margin': r'{margin-width}(\s+{margin-width}){0,3}|inherit', + 'max-height': r'{length}|{percentage}|none|inherit', + 'max-width': r'{length}|{percentage}|none|inherit', + 'min-height': r'{length}|{percentage}|none|inherit', + 'min-width': r'{length}|{percentage}|none|inherit', + 'orphans': r'{integer}|inherit', + 'outline-color': r'{outline-color}', + 'outline-style': r'{outline-style}', + 'outline-width': r'{outline-width}', + 'outline': r'{outline-attrs}(\s+{outline-attrs})*|inherit', + 'overflow': r'visible|hidden|scroll|auto|inherit', + 'padding-top': r'{padding-width}|inherit', + 'padding-right': r'{padding-width}|inherit', + 'padding-bottom': r'{padding-width}|inherit', + 'padding-left': r'{padding-width}|inherit', + 'padding': r'{padding-width}(\s+{padding-width}){0,3}|inherit', + 'page-break-after': r'auto|always|avoid|left|right|inherit', + 'page-break-before': r'auto|always|avoid|left|right|inherit', + 'page-break-inside': r'avoid|auto|inherit', + 'pause-after': r'{time}|{percentage}|inherit', + 'pause-before': r'{time}|{percentage}|inherit', + 'pause': r'({time}|{percentage}){1,2}|inherit', + 'pitch-range': r'{number}|inherit', + 'pitch': r'{frequency}|x-low|low|medium|high|x-high|inherit', + 'play-during': r'{uri}(\s+(mix|repeat))*|auto|none|inherit', + 'position': r'static|relative|absolute|fixed|inherit', + 'quotes': r'({string}\s+{string})(\s+{string}\s+{string})*|none|inherit', + 'richness': r'{number}|inherit', + 'right': r'{length}|{percentage}|auto|inherit', + 'speak-header': r'once|always|inherit', + 'speak-numeral': r'digits|continuous|inherit', + 'speak-punctuation': r'code|none|inherit', + 'speak': r'normal|none|spell-out|inherit', + 'speech-rate': r'{number}|x-slow|slow|medium|fast|x-fast|faster|slower|inherit', + 'stress': r'{number}|inherit', + 'table-layout': r'auto|fixed|inherit', + 'text-align': r'left|right|center|justify|inherit', + 'text-decoration': r'none|{text-attrs}(\s+{text-attrs})*|inherit', + 'text-indent': r'{length}|{percentage}|inherit', + 'text-transform': r'capitalize|uppercase|lowercase|none|inherit', + 'top': r'{length}|{percentage}|auto|inherit', + 'unicode-bidi': r'normal|embed|bidi-override|inherit', + 'vertical-align': r'baseline|sub|super|top|text-top|middle|bottom|text-bottom|{percentage}|{length}|inherit', + 'visibility': r'visible|hidden|collapse|inherit', + 'voice-family': r'({specific-voice}|{generic-voice}{w},{w})*({specific-voice}|{generic-voice})|inherit', + 'volume': r'{number}|{percentage}|silent|x-soft|soft|medium|loud|x-loud|inherit', + 'white-space': r'normal|pre|nowrap|pre-wrap|pre-line|inherit', + 'widows': r'{integer}|inherit', + 'width': r'{length}|{percentage}|auto|inherit', + 'word-spacing': r'normal|{length}|inherit', + 'z-index': r'auto|{integer}|inherit', +} + +# CSS Color Module Level 3 +css3colormacros = { + # orange and transparent in CSS 2.1 + 'namedcolor': r'(currentcolor|transparent|orange|black|green|silver|lime|gray|olive|white|yellow|maroon|navy|red|blue|purple|teal|fuchsia|aqua)', + # orange? + 'rgbacolor': r'rgba\({w}{int}{w},{w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgba\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w},{w}{num}{w}\)', + 'hslcolor': r'hsl\({w}{int}{w},{w}{num}%{w},{w}{num}%{w}\)|hsla\({w}{int}{w},{w}{num}%{w},{w}{num}%{w},{w}{num}{w}\)', + } + + +css3color = { + 'color': r'{namedcolor}|{hexcolor}|{rgbcolor}|{rgbacolor}|{hslcolor}|inherit', + 'opacity': r'{num}|inherit' + } + +class NoSuchProfileException(Exception): + """Raised if no profile with given name is found""" + pass + + +class Profiles(object): + """ + A dictionary of:: + + profilename: { + propname: propvalue_regex* + } + + Predefined profiles are: + + - 'CSS level 2': Properties defined by CSS2 + + """ + basicmacros = { + 'ident': r'[-]?{nmstart}{nmchar}*', + 'name': r'{nmchar}+', + 'nmstart': r'[_a-z]|{nonascii}|{escape}', + 'nonascii': r'[^\0-\177]', + 'unicode': r'\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?', + 'escape': r'{unicode}|\\[ -~\200-\777]', + # 'escape': r'{unicode}|\\[ -~\200-\4177777]', + 'int': r'[-]?\d+', + 'nmchar': r'[\w-]|{nonascii}|{escape}', + 'num': r'[-]?\d+|[-]?\d*\.\d+', + 'number': r'{num}', + 'string': r'{string1}|{string2}', + 'string1': r'"(\\\"|[^\"])*"', + 'uri': r'url\({w}({string}|(\\\)|[^\)])+){w}\)', + 'string2': r"'(\\\'|[^\'])*'", + 'nl': r'\n|\r\n|\r|\f', + 'w': r'\s*', + } + generalmacros = { + 'hexcolor': r'#[0-9a-f]{3}|#[0-9a-f]{6}', + 'rgbcolor': r'rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)', + 'namedcolor': r'(transparent|orange|maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray)', + 'uicolor': r'(ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)', + 'color': r'{namedcolor}|{hexcolor}|{rgbcolor}|{uicolor}', + #'color': r'(maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)|#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)', + 'integer': r'{int}', + 'length': r'0|{num}(em|ex|px|in|cm|mm|pt|pc)', + 'angle': r'0|{num}(deg|grad|rad)', + 'time': r'0|{num}m?s', + 'frequency': r'0|{num}k?Hz', + 'percentage': r'{num}%', + } + + CSS_LEVEL_2 = 'CSS Level 2.1' + CSS_COLOR_LEVEL_3 = 'CSS Color Module Level 3' + + def __init__(self): + self._log = cssutils.log + self._profilenames = [] # to keep order, REFACTOR! + self._profiles = {} + self.addProfile(self.CSS_LEVEL_2, css2, css2macros) + self.addProfile(self.CSS_COLOR_LEVEL_3, css3color, css3colormacros) + + def _expand_macros(self, dictionary, macros): + """Expand macros in token dictionary""" + def macro_value(m): + return '(?:%s)' % macros[m.groupdict()['macro']] + for key, value in dictionary.items(): + if not callable(value): + while re.search(r'{[a-z][a-z0-9-]*}', value): + value = re.sub(r'{(?P<macro>[a-z][a-z0-9-]*)}', + macro_value, value) + dictionary[key] = value + return dictionary + + def _compile_regexes(self, dictionary): + """Compile all regular expressions into callable objects""" + for key, value in dictionary.items(): + if not callable(value): + value = re.compile('^(?:%s)$' % value, re.I).match + dictionary[key] = value + + return dictionary + + profiles = property(lambda self: sorted(self._profiles.keys()), + doc=u'Names of all profiles.') + + def addProfile(self, profile, properties, macros=None): + """Add a new profile with name ``profile`` (e.g. 'CSS level 2') + and the given ``properties``. ``macros`` are + + ``profile`` + The new profile's name + ``properties`` + A dictionary of ``{ property-name: propery-value }`` items where + property-value is a regex which may use macros defined in given + ``macros`` or the standard macros Profiles.tokens and + Profiles.generalvalues. + + ``propery-value`` may also be a function which takes a single + argument which is the value to validate and which should return + True or False. + Any exceptions which may be raised during this custom validation + are reported or raised as all other cssutils exceptions depending + on cssutils.log.raiseExceptions which e.g during parsing normally + is False so the exceptions would be logged only. + """ + if not macros: + macros = {} + m = self.basicmacros + m.update(self.generalmacros) + m.update(macros) + properties = self._expand_macros(properties, m) + self._profilenames.append(profile) + self._profiles[profile] = self._compile_regexes(properties) + + def propertiesByProfile(self, profiles=None): + """Generator: Yield property names, if no profile(s) is given all + profile's properties are used.""" + if not profiles: + profiles = self.profiles + elif isinstance(profiles, basestring): + profiles = (profiles, ) + + try: + for profile in sorted(profiles): + for name in sorted(self._profiles[profile].keys()): + yield name + except KeyError, e: + raise NoSuchProfileException(e) + + def validate(self, name, value): + """Check if value is valid for given property name using any profile.""" + for profile in self.profiles: + if name in self._profiles[profile]: + try: + # custom validation errors are caught + r = bool(self._profiles[profile][name](value)) + except Exception, e: + self._log.error(e, error=Exception) + return False + if r: + return r + return False + + def validateWithProfile(self, name, value): + """Check if value is valid for given property name returning + (valid, valid_in_profile). + + You may want to check if valid_in_profile is what you expected. + + Example: You might expect a valid Profiles.CSS_LEVEL_2 value but + e.g. ``validateWithProfile('color', 'rgba(1,1,1,1)')`` returns + (True, Profiles.CSS_COLOR_LEVEL_3) + """ + for profilename in self._profilenames: + if name in self._profiles[profilename]: + try: + # custom validation errors are caught + r = (bool(self._profiles[profilename][name](value)), + profilename) + except Exception, e: + self._log.error(e, error=Exception) + r = False, None + if r[0]: + return r + return False, None + + +profiles = Profiles() + diff --git a/src/cssutils/script.py b/src/cssutils/script.py new file mode 100644 index 0000000000..b016ead9a0 --- /dev/null +++ b/src/cssutils/script.py @@ -0,0 +1,371 @@ +"""classes and functions used by cssutils scripts +""" +__all__ = ['CSSCapture', 'csscombine'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: parse.py 1323 2008-07-06 18:13:57Z cthedot $' + +import codecs +import errno +import HTMLParser +import logging +import os +import sys +import urllib2 +import urlparse + +import cssutils +try: + import cssutils.encutils as encutils +except ImportError: + try: + import encutils + except ImportError: + sys.exit("You need encutils from http://cthedot.de/encutils/") + +# types of sheets in HTML +LINK = 0 # <link rel="stylesheet" type="text/css" href="..." [@title="..." @media="..."]/> +STYLE = 1 # <style type="text/css" [@title="..."]>...</style> + +class CSSCaptureHTMLParser(HTMLParser.HTMLParser): + """CSSCapture helper: Parse given data for link and style elements""" + curtag = u'' + sheets = [] # (type, [atts, cssText]) + + def _loweratts(self, atts): + return dict([(a.lower(), v.lower()) for a, v in atts]) + + def handle_starttag(self, tag, atts): + if tag == u'link': + atts = self._loweratts(atts) + if u'text/css' == atts.get(u'type', u''): + self.sheets.append((LINK, atts)) + elif tag == u'style': + # also get content of style + atts = self._loweratts(atts) + if u'text/css' == atts.get(u'type', u''): + self.sheets.append((STYLE, [atts, u''])) + self.curtag = tag + else: + # close as only intersting <style> cannot contain any elements + self.curtag = u'' + + def handle_data(self, data): + if self.curtag == u'style': + self.sheets[-1][1][1] = data # replace cssText + + def handle_comment(self, data): + # style might have comment content, treat same as data + self.handle_data(data) + + def handle_endtag(self, tag): + # close as style cannot contain any elements + self.curtag = u'' + + +class CSSCapture(object): + """ + Retrieve all CSS stylesheets including embedded for a given URL. + Optional setting of User-Agent used for retrieval possible + to handle browser sniffing servers. + + raises urllib2.HTTPError + """ + def __init__(self, ua=None, log=None, defaultloglevel=logging.INFO): + """ + initialize a new Capture object + + ua + init User-Agent to use for requests + log + supply a log object which is used instead of the default + log which writes to sys.stderr + defaultloglevel + constant of logging package which defines the level of the + default log if no explicit log given + """ + self._ua = ua + + if log: + self._log = log + else: + self._log = logging.getLogger('CSSCapture') + hdlr = logging.StreamHandler(sys.stderr) + formatter = logging.Formatter('%(message)s') + hdlr.setFormatter(formatter) + self._log.addHandler(hdlr) + self._log.setLevel(defaultloglevel) + self._log.debug(u'Using default log') + + self._htmlparser = CSSCaptureHTMLParser() + self._cssparser = cssutils.CSSParser(log = self._log) + + def _doRequest(self, url): + """Do an HTTP request + + Return (url, rawcontent) + url might have been changed by server due to redirects etc + """ + self._log.debug(u' CSSCapture._doRequest\n * URL: %s' % url) + + req = urllib2.Request(url) + if self._ua: + req.add_header('User-agent', self._ua) + self._log.info(' * Using User-Agent: %s', self._ua) + + try: + res = urllib2.urlopen(req) + except urllib2.HTTPError, e: + self._log.critical(' %s\n%s %s\n%s' % ( + e.geturl(), e.code, e.msg, e.headers)) + return None, None + + # get real url + if url != res.geturl(): + url = res.geturl() + self._log.info(' URL retrieved: %s', url) + + return url, res + + def _createStyleSheet(self, href=None, + media=None, + parentStyleSheet=None, + title=u'', + cssText=None, + encoding=None): + """ + Return CSSStyleSheet read from href or if cssText is given use that. + + encoding + used if inline style found, same as self.docencoding + """ + if cssText is None: + encoding, enctype, cssText = cssutils.util._readUrl(href, parentEncoding=self.docencoding) + encoding = None # already decoded??? + + sheet = self._cssparser.parseString(cssText, href=href, media=media, title=title, + encoding=encoding) + + if not sheet: + return None + + else: + self._log.info(u' %s\n' % sheet) + self._nonparsed[sheet] = cssText + return sheet + + def _findStyleSheets(self, docurl, doctext): + """ + parse text for stylesheets + fills stylesheetlist with all found StyleSheets + + docurl + to build a full url of found StyleSheets @href + doctext + to parse + """ + # TODO: ownerNode should be set to the <link> node + self._htmlparser.feed(doctext) + + for typ, data in self._htmlparser.sheets: + sheet = None + + if LINK == typ: + self._log.info(u'+ PROCESSING <link> %r' % data) + + atts = data + href = urlparse.urljoin(docurl, atts.get(u'href', None)) + sheet = self._createStyleSheet(href=href, + media=atts.get(u'media', None), + title=atts.get(u'title', None)) + elif STYLE == typ: + self._log.info(u'+ PROCESSING <style> %r' % data) + + atts, cssText = data + sheet = self._createStyleSheet(cssText=cssText, + href = docurl, + media=atts.get(u'media', None), + title=atts.get(u'title', None), + encoding=self.docencoding) + if sheet: + sheet._href = None # inline have no href! + print sheet.cssText + + if sheet: + self.stylesheetlist.append(sheet) + self._doImports(sheet, base=docurl) + + + def _doImports(self, parentStyleSheet, base=None): + """ + handle all @import CSS stylesheet recursively + found CSS stylesheets are appended to stylesheetlist + """ + # TODO: only if not parsed these have to be read extra! + + for rule in parentStyleSheet.cssRules: + if rule.type == rule.IMPORT_RULE: + self._log.info(u'+ PROCESSING @import:') + self._log.debug(u' IN: %s\n' % parentStyleSheet.href) + sheet = rule.styleSheet + href = urlparse.urljoin(base, rule.href) + if sheet: + self._log.info(u' %s\n' % sheet) + self.stylesheetlist.append(sheet) + self._doImports(sheet, base=href) + + def capture(self, url): + """ + Capture all stylesheets at given URL's HTML document. + Any HTTPError is raised to caller. + + url + to capture CSS from + + Returns ``cssutils.stylesheets.StyleSheetList``. + """ + self._log.info(u'\nCapturing CSS from URL:\n %s\n', url) + self._nonparsed = {} + self.stylesheetlist = cssutils.stylesheets.StyleSheetList() + + # used to save inline styles + scheme, loc, path, query, fragment = urlparse.urlsplit(url) + self._filename = os.path.basename(path) + + # get url content + url, res = self._doRequest(url) + if not res: + sys.exit(1) + + rawdoc = res.read() + + self.docencoding = encutils.getEncodingInfo( + res, rawdoc, log=self._log).encoding + self._log.info(u'\nUsing Encoding: %s\n', self.docencoding) + + doctext = rawdoc.decode(self.docencoding) + + # fill list of stylesheets and list of raw css + self._findStyleSheets(url, doctext) + + return self.stylesheetlist + + def saveto(self, dir, saveraw=False, minified=False): + """ + saves css in "dir" in the same layout as on the server + internal stylesheets are saved as "dir/__INLINE_STYLE__.html.css" + + dir + directory to save files to + saveparsed + save literal CSS from server or save the parsed CSS + minified + save minified CSS + + Both parsed and minified (which is also parsed of course) will + loose information which cssutils is unable to understand or where + it is simple buggy. You might to first save the raw version before + parsing of even minifying it. + """ + msg = 'parsed' + if saveraw: + msg = 'raw' + if minified: + cssutils.ser.prefs.useMinified() + msg = 'minified' + + inlines = 0 + for i, sheet in enumerate(self.stylesheetlist): + url = sheet.href + if not url: + inlines += 1 + url = u'%s_INLINE_%s.css' % (self._filename, inlines) + + # build savepath + scheme, loc, path, query, fragment = urlparse.urlsplit(url) + # no absolute path + if path and path.startswith('/'): + path = path[1:] + path = os.path.normpath(path) + path, fn = os.path.split(path) + savepath = os.path.join(dir, path) + savefn = os.path.join(savepath, fn) + try: + os.makedirs(savepath) + except OSError, e: + if e.errno != errno.EEXIST: + raise e + self._log.debug(u'Path "%s" already exists.', savepath) + + self._log.info(u'SAVING %s, %s %r' % (i+1, msg, savefn)) + + sf = open(savefn, 'wb') + if saveraw: + cssText = self._nonparsed[sheet] + uf = codecs.getwriter('css')(sf) + uf.write(cssText) + else: + sf.write(sheet.cssText) + sf.close() + + +def csscombine(proxypath, sourceencoding=None, targetencoding='utf-8', + minify=True): + """Combine sheets referred to by @import rules in given CSS proxy sheet +into a single new sheet. + + :returns: combined cssText, normal or minified + :Parameters: + `proxypath` + url or path to a CSSStyleSheet which imports other sheets which + are then combined into one sheet + `sourceencoding` + encoding of the source sheets including the proxy sheet + `targetencoding` + encoding of the combined stylesheet, default 'utf-8' + `minify` + defines if the combined sheet should be minified, default True + """ + log = cssutils.log + + log.info('Combining files in proxy %r' % proxypath, neverraise=True) + + if sourceencoding is not None: + log.info('Using source encoding %r' % sourceencoding, + neverraise=True) + + src = cssutils.parseFile(proxypath, encoding=sourceencoding) + srcpath = os.path.dirname(proxypath) + combined = cssutils.css.CSSStyleSheet() + for rule in src.cssRules: + if rule.type == rule.IMPORT_RULE: + fn = os.path.join(srcpath, rule.href) + log.info('Processing @import %r' % fn, + neverraise=True) + importsheet = cssutils.parseFile(fn, encoding=sourceencoding) + importsheet.encoding = None # remove @charset + combined.add(cssutils.css.CSSComment(cssText=u'/* %s */' % + rule.cssText)) + for x in importsheet.cssRules: + if x.type == x.IMPORT_RULE: + log.info('Nested @imports are not combined: %s' % x.cssText, + neverraise=True) + + combined.add(x) + + else: + combined.add(rule) + + log.info('Setting target encoding %r' % targetencoding, neverraise=True) + combined.encoding = targetencoding + + if minify: + # save old setting and use own serializer + oldser = cssutils.ser + cssutils.setSerializer(cssutils.serialize.CSSSerializer()) + cssutils.ser.prefs.useMinified() + cssText = combined.cssText + cssutils.setSerializer(oldser) + else: + cssText = combined.cssText + + return cssText diff --git a/src/cssutils/serialize.py b/src/cssutils/serialize.py new file mode 100644 index 0000000000..a21eb6aed1 --- /dev/null +++ b/src/cssutils/serialize.py @@ -0,0 +1,962 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""serializer classes for CSS classes + +""" +__all__ = ['CSSSerializer', 'Preferences'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: serialize.py 1472 2008-09-15 21:14:54Z cthedot $' +import codecs +import re +import xml.dom +import cssutils + +def _escapecss(e): + """ + Escapes characters not allowed in the current encoding the CSS way + with a backslash followed by a uppercase hex code point + + E.g. the german umlaut 'ä' is escaped as \E4 + """ + s = e.object[e.start:e.end] + return u''.join([ur'\%s ' % str(hex(ord(x)))[2:] # remove 0x from hex + .upper() for x in s]), e.end + +codecs.register_error('escapecss', _escapecss) + + +class Preferences(object): + """ + controls output of CSSSerializer + + defaultAtKeyword = True + Should the literal @keyword from src CSS be used or the default + form, e.g. if ``True``: ``@import`` else: ``@i\mport`` + defaultPropertyName = True + Should the normalized propertyname be used or the one given in + the src file, e.g. if ``True``: ``color`` else: ``c\olor`` + + Only used if ``keepAllProperties==False``. + + defaultPropertyPriority = True + Should the normalized or literal priority be used, e.g. '!important' + or u'!Im\portant' + + importHrefFormat = None + Uses hreftype if ``None`` or explicit ``'string'`` or ``'uri'`` + indent = 4 * ' ' + Indentation of e.g Properties inside a CSSStyleDeclaration + indentSpecificities = False + Indent rules with subset of Selectors and higher Specitivity + + keepAllProperties = True + If ``True`` all properties set in the original CSSStylesheet + are kept meaning even properties set twice with the exact same + same name are kept! + keepComments = True + If ``False`` removes all CSSComments + keepEmptyRules = False + defines if empty rules like e.g. ``a {}`` are kept in the resulting + serialized sheet + keepUsedNamespaceRulesOnly = False + if True only namespace rules which are actually used are kept + + lineNumbers = False + Only used if a complete CSSStyleSheet is serialized. + lineSeparator = u'\\n' + How to end a line. This may be set to e.g. u'' for serializing of + CSSStyleDeclarations usable in HTML style attribute. + listItemSpacer = u' ' + string which is used in ``css.SelectorList``, ``css.CSSValue`` and + ``stylesheets.MediaList`` after the comma + omitLastSemicolon = True + If ``True`` omits ; after last property of CSSStyleDeclaration + paranthesisSpacer = u' ' + string which is used before an opening paranthesis like in a + ``css.CSSMediaRule`` or ``css.CSSStyleRule`` + propertyNameSpacer = u' ' + string which is used after a Property name colon + selectorCombinatorSpacer = u' ' + string which is used before and after a Selector combinator like +, > or ~. + CSSOM defines a single space for this which is also the default in cssutils. + spacer = u' ' + general spacer, used e.g. by CSSUnknownRule + + validOnly = False **DO NOT CHANGE YET** + if True only valid (currently Properties) are kept + + A Property is valid if it is a known Property with a valid value. + Currently CSS 2.1 values as defined in cssproperties.py would be + valid. + + """ + def __init__(self, **initials): + """ + Always use named instead of positional parameters + """ + self.useDefaults() + + for key, value in initials.items(): + if value: + self.__setattr__(key, value) + + def useDefaults(self): + "reset all preference options to the default value" + self.defaultAtKeyword = True + self.defaultPropertyName = True + self.defaultPropertyPriority = True + self.importHrefFormat = None + self.indent = 4 * u' ' + self.indentSpecificities = False + self.keepAllProperties = True + self.keepComments = True + self.keepEmptyRules = False + self.keepUsedNamespaceRulesOnly = False + self.lineNumbers = False + self.lineSeparator = u'\n' + self.listItemSpacer = u' ' + self.omitLastSemicolon = True + self.paranthesisSpacer = u' ' + self.propertyNameSpacer = u' ' + self.selectorCombinatorSpacer = u' ' + self.spacer = u' ' + self.validOnly = False # should not be changed currently!!! + + def useMinified(self): + """ + sets options to achive a minified stylesheet + + you may want to set preferences with this convenience method + and set settings you want adjusted afterwards + """ + self.importHrefFormat = 'string' + self.indent = u'' + self.keepComments = False + self.keepEmptyRules = False + self.keepUsedNamespaceRulesOnly = True + self.lineNumbers = False + self.lineSeparator = u'' + self.listItemSpacer = u'' + self.omitLastSemicolon = True + self.paranthesisSpacer = u'' + self.propertyNameSpacer = u'' + self.selectorCombinatorSpacer = u'' + self.spacer = u'' + self.validOnly = False + + def __repr__(self): + return u"cssutils.css.%s(%s)" % (self.__class__.__name__, + u', '.join(['\n %s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__] + )) + + def __str__(self): + return u"<cssutils.css.%s object %s at 0x%x" % (self.__class__.__name__, + u' '.join(['%s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__] + ), + id(self)) + + +class Out(object): + """ + a simple class which makes appended items available as a combined string + """ + def __init__(self, ser): + self.ser = ser + self.out = [] + + def _remove_last_if_S(self): + if self.out and not self.out[-1].strip(): + # remove trailing S + del self.out[-1] + + def append(self, val, typ=None, space=True, keepS=False, indent=False, + lineSeparator=False): + """Appends val. Adds a single S after each token except as follows: + + - typ COMMENT + uses cssText depending on self.ser.prefs.keepComments + - typ "Property", cssutils.css.CSSRule.UNKNOWN_RULE + uses cssText + - typ STRING + escapes ser._string + - typ S + ignored except ``keepS=True`` + - typ URI + calls ser_uri + - val ``{`` + adds LF after + - val ``;`` + removes S before and adds LF after + - val ``, :`` + removes S before + - val ``+ > ~`` + encloses in prefs.selectorCombinatorSpacer + - some other vals + add ``*spacer`` except ``space=False`` + """ + if val or typ in ('STRING', 'URI'): + # PRE + if 'COMMENT' == typ: + if self.ser.prefs.keepComments: + val = val.cssText + else: + return + elif hasattr(val, 'cssText'): + val = val.cssText +# elif typ in ('Property', cssutils.css.CSSRule.UNKNOWN_RULE): +# val = val.cssText + elif 'S' == typ and not keepS: + return + elif typ in ('NUMBER', 'DIMENSION', 'PERCENTAGE') and val == '0': + # remove sign + or - if value is zero + # TODO: only for lenghts! + if self.out and self.out[-1] in u'+-': + del self.out[-1] + elif 'STRING' == typ: + # may be empty but MUST not be None + if val is None: + return + val = self.ser._string(val) + elif 'URI' == typ: + val = self.ser._uri(val) + elif val in u'+>~,:{;)]/': + self._remove_last_if_S() + + # APPEND + if indent: + self.out.append(self.ser._indentblock(val, self.ser._level+1)) + else: + self.out.append(val) + # POST + if lineSeparator: + # Property , ... + pass + elif val in u'+>~': # enclose selector combinator + self.out.insert(-1, self.ser.prefs.selectorCombinatorSpacer) + self.out.append(self.ser.prefs.selectorCombinatorSpacer) + elif u',' == val: # list + self.out.append(self.ser.prefs.listItemSpacer) + elif u':' == val: # prop + self.out.append(self.ser.prefs.propertyNameSpacer) + elif u'{' == val: # block start + self.out.insert(-1, self.ser.prefs.paranthesisSpacer) + self.out.append(self.ser.prefs.lineSeparator) + elif u';' == val: # end or prop or block + self.out.append(self.ser.prefs.lineSeparator) + elif val not in u'}[]()/' and typ not in ('FUNCTION',) and space: + self.out.append(self.ser.prefs.spacer) + + def value(self, delim=u'', end=None, keepS=False): + "returns all items joined by delim" + if not keepS: + self._remove_last_if_S() + if end: + self.out.append(end) + return delim.join(self.out) + + +class CSSSerializer(object): + """ + Methods to serialize a CSSStylesheet and its parts + + To use your own serializing method the easiest is to subclass CSS + Serializer and overwrite the methods you like to customize. + """ + # chars not in URI without quotes around as problematic with other stuff + # really ","? + __forbidden_in_uri_matcher = re.compile(ur'''.*?[\(\)\s\;,]''', re.U).match + + def __init__(self, prefs=None): + """ + prefs + instance of Preferences + """ + if not prefs: + prefs = Preferences() + self.prefs = prefs + self._level = 0 # current nesting level + + # TODO: + self._selectors = [] # holds SelectorList + self._selectorlevel = 0 # current specificity nesting level + + def _atkeyword(self, rule, default): + "returns default or source atkeyword depending on prefs" + if self.prefs.defaultAtKeyword: + return default + else: + return rule.atkeyword + + def _indentblock(self, text, level): + """ + indent a block like a CSSStyleDeclaration to the given level + which may be higher than self._level (e.g. for CSSStyleDeclaration) + """ + if not self.prefs.lineSeparator: + return text + return self.prefs.lineSeparator.join( + [u'%s%s' % (level * self.prefs.indent, line) + for line in text.split(self.prefs.lineSeparator)] + ) + + def _propertyname(self, property, actual): + """ + used by all styledeclarations to get the propertyname used + dependent on prefs setting defaultPropertyName and + keepAllProperties + """ + if self.prefs.defaultPropertyName and not self.prefs.keepAllProperties: + return property.name + else: + return actual + + def _linenumnbers(self, text): + if self.prefs.lineNumbers: + pad = len(str(text.count(self.prefs.lineSeparator)+1)) + out = [] + for i, line in enumerate(text.split(self.prefs.lineSeparator)): + out.append((u'%*i: %s') % (pad, i+1, line)) + text = self.prefs.lineSeparator.join(out) + return text + + def _string(self, s): + """ + returns s encloded between "..." and escaped delim charater ", + escape line breaks \\n \\r and \\f + """ + # \n = 0xa, \r = 0xd, \f = 0xc + s = s.replace('\n', '\\a ').replace( + '\r', '\\d ').replace( + '\f', '\\c ') + return u'"%s"' % s.replace('"', u'\\"') + + def _uri(self, uri): + """returns uri enclosed in url() and "..." if necessary""" + if CSSSerializer.__forbidden_in_uri_matcher(uri): + return 'url(%s)' % self._string(uri) + else: + return 'url(%s)' % uri + + def _valid(self, x): + "checks items valid property and prefs.validOnly" + return not self.prefs.validOnly or (self.prefs.validOnly and + x.valid) + + def do_CSSStyleSheet(self, stylesheet): + """serializes a complete CSSStyleSheet""" + useduris = stylesheet._getUsedURIs() + out = [] + for rule in stylesheet.cssRules: + if self.prefs.keepUsedNamespaceRulesOnly and\ + rule.NAMESPACE_RULE == rule.type and\ + rule.namespaceURI not in useduris and ( + rule.prefix or None not in useduris): + continue + + cssText = rule.cssText + if cssText: + out.append(cssText) + text = self._linenumnbers(self.prefs.lineSeparator.join(out)) + + # get encoding of sheet, defaults to UTF-8 + try: + encoding = stylesheet.cssRules[0].encoding + except (IndexError, AttributeError): + encoding = 'UTF-8' + + return text.encode(encoding, 'escapecss') + + def do_CSSComment(self, rule): + """ + serializes CSSComment which consists only of commentText + """ + if rule._cssText and self.prefs.keepComments: + return rule._cssText + else: + return u'' + + def do_CSSCharsetRule(self, rule): + """ + serializes CSSCharsetRule + encoding: string + + always @charset "encoding"; + no comments or other things allowed! + """ + if rule.wellformed: + return u'@charset %s;' % self._string(rule.encoding) + else: + return u'' + + def do_CSSFontFaceRule(self, rule): + """ + serializes CSSFontFaceRule + + style + CSSStyleDeclaration + + + CSSComments + """ + styleText = self.do_css_CSSStyleDeclaration(rule.style) + + if styleText and rule.wellformed: + out = Out(self) + out.append(self._atkeyword(rule, u'@font-face')) + for item in rule.seq: + # assume comments { + out.append(item.value, item.type) + out.append(u'{') + out.append(u'%s%s}' % (styleText, self.prefs.lineSeparator), + indent=1) + return out.value() + else: + return u'' + + def do_CSSImportRule(self, rule): + """ + serializes CSSImportRule + + href + string + media + optional cssutils.stylesheets.medialist.MediaList + name + optional string + + + CSSComments + """ + if rule.wellformed: + out = Out(self) + out.append(self._atkeyword(rule, u'@import')) + + for item in rule.seq: + typ, val = item.type, item.value + if 'href' == typ: + # "href" or url(href) + if self.prefs.importHrefFormat == 'string' or ( + self.prefs.importHrefFormat != 'uri' and + rule.hreftype == 'string'): + out.append(val, 'STRING') + else: + if not len(self.prefs.spacer): + out.append(u' ') + out.append(val, 'URI') + elif 'media' == typ: + # media + mediaText = self.do_stylesheets_medialist(val) + if mediaText and mediaText != u'all': + out.append(mediaText) + elif 'name' == typ: + out.append(val, 'STRING') + else: + out.append(val, typ) + + return out.value(end=u';') + else: + return u'' + + def do_CSSNamespaceRule(self, rule): + """ + serializes CSSNamespaceRule + + uri + string + prefix + string + + + CSSComments + """ + if rule.wellformed: + out = Out(self) + out.append(self._atkeyword(rule, u'@namespace')) + if not len(self.prefs.spacer): + out.append(u' ') + + for item in rule.seq: + typ, val = item.type, item.value + if 'namespaceURI' == typ: + out.append(val, 'STRING') + else: + out.append(val, typ) + + return out.value(end=u';') + else: + return u'' + + def do_CSSMediaRule(self, rule): + """ + serializes CSSMediaRule + + + CSSComments + """ + # TODO: use Out()? + + # mediaquery + if not rule.media.wellformed: + return u'' + + # @media + out = [self._atkeyword(rule, u'@media')] + if not len(self.prefs.spacer): + # for now always with space as only webkit supports @mediaall? + out.append(u' ') + else: + out.append(self.prefs.spacer) # might be empty + + out.append(self.do_stylesheets_medialist(rule.media)) + + # name, seq contains content after name only (Comments) + if rule.name: + out.append(self.prefs.spacer) + nameout = Out(self) + nameout.append(self._string(rule.name)) + for item in rule.seq: + nameout.append(item.value, item.type) + out.append(nameout.value()) + + # { + out.append(self.prefs.paranthesisSpacer) + out.append(u'{') + out.append(self.prefs.lineSeparator) + + # rules + rulesout = [] + for r in rule.cssRules: + rtext = r.cssText + if rtext: + # indent each line of cssText + rulesout.append(self._indentblock(rtext, self._level + 1)) + rulesout.append(self.prefs.lineSeparator) + if not self.prefs.keepEmptyRules and not u''.join(rulesout).strip(): + return u'' + out.extend(rulesout) + + # } + out.append(u'%s}' % ((self._level + 1) * self.prefs.indent)) + + return u''.join(out) + + def do_CSSPageRule(self, rule): + """ + serializes CSSPageRule + + selectorText + string + style + CSSStyleDeclaration + + + CSSComments + """ + styleText = self.do_css_CSSStyleDeclaration(rule.style) + + if styleText and rule.wellformed: + out = Out(self) + out.append(self._atkeyword(rule, u'@page')) + if not len(self.prefs.spacer): + out.append(u' ') + + for item in rule.seq: + out.append(item.value, item.type) + + out.append(u'{') + out.append(u'%s%s}' % (styleText, self.prefs.lineSeparator), + indent=1) + return out.value() + else: + return u'' + + def do_CSSUnknownRule(self, rule): + """ + serializes CSSUnknownRule + anything until ";" or "{...}" + + CSSComments + """ + if rule.wellformed: + out = Out(self) + out.append(rule.atkeyword) + if not len(self.prefs.spacer): + out.append(u' ') + + stacks = [] + for item in rule.seq: + typ, val = item.type, item.value + # PRE + if u'}' == val: + # close last open item on stack + stackblock = stacks.pop().value() + if stackblock: + val = self._indentblock( + stackblock + self.prefs.lineSeparator + val, + min(1, len(stacks)+1)) + else: + val = self._indentblock(val, min(1, len(stacks)+1)) + # APPEND + if stacks: + stacks[-1].append(val, typ) + else: + out.append(val, typ) + + # POST + if u'{' == val: + # new stack level + stacks.append(Out(self)) + + return out.value() + else: + return u'' + + def do_CSSStyleRule(self, rule): + """ + serializes CSSStyleRule + + selectorList + style + + + CSSComments + """ + # TODO: use Out() + + # prepare for element nested rules + # TODO: sort selectors! + if self.prefs.indentSpecificities: + # subselectorlist? + elements = set([s.element for s in rule.selectorList]) + specitivities = [s.specificity for s in rule.selectorList] + for selector in self._selectors: + lastelements = set([s.element for s in selector]) + if elements.issubset(lastelements): + # higher specificity? + lastspecitivities = [s.specificity for s in selector] + if specitivities > lastspecitivities: + self._selectorlevel += 1 + break + elif self._selectorlevel > 0: + self._selectorlevel -= 1 + else: + # save new reference + self._selectors.append(rule.selectorList) + self._selectorlevel = 0 + + # TODO ^ RESOLVE!!!! + + selectorText = self.do_css_SelectorList(rule.selectorList) + if not selectorText or not rule.wellformed: + return u'' + self._level += 1 + styleText = u'' + try: + styleText = self.do_css_CSSStyleDeclaration(rule.style) + finally: + self._level -= 1 + if not styleText: + if self.prefs.keepEmptyRules: + return u'%s%s{}' % (selectorText, + self.prefs.paranthesisSpacer) + else: + return self._indentblock( + u'%s%s{%s%s%s%s}' % ( + selectorText, + self.prefs.paranthesisSpacer, + self.prefs.lineSeparator, + self._indentblock(styleText, self._level + 1), + self.prefs.lineSeparator, + (self._level + 1) * self.prefs.indent), + self._selectorlevel) + + def do_css_SelectorList(self, selectorlist): + "comma-separated list of Selectors" + # does not need Out() as it is too simple + if selectorlist.wellformed: + out = [] + for part in selectorlist.seq: + if isinstance(part, cssutils.css.Selector): + out.append(part.selectorText) + else: + out.append(part) # should not happen + sep = u',%s' % self.prefs.listItemSpacer + return sep.join(out) + else: + return u'' + + def do_css_Selector(self, selector): + """ + a single Selector including comments + + an element has syntax (namespaceURI, name) where namespaceURI may be: + + - cssutils._ANYNS => ``*|name`` + - None => ``name`` + - u'' => ``|name`` + - any other value: => ``prefix|name`` + """ + if selector.wellformed: + out = Out(self) + + DEFAULTURI = selector._namespaces.get('', None) + for item in selector.seq: + typ, val = item.type, item.value + if type(val) == tuple: + # namespaceURI|name (element or attribute) + namespaceURI, name = val + if DEFAULTURI == namespaceURI or (not DEFAULTURI and + namespaceURI is None): + out.append(name, typ, space=False) + else: + if namespaceURI == cssutils._ANYNS: + prefix = u'*' + else: + try: + prefix = selector._namespaces.prefixForNamespaceURI( + namespaceURI) + except IndexError: + prefix = u'' + + out.append(u'%s|%s' % (prefix, name), typ, space=False) + else: + out.append(val, typ, space=False, keepS=True) + + return out.value() + else: + return u'' + + def do_css_CSSStyleDeclaration(self, style, separator=None): + """ + Style declaration of CSSStyleRule + """ +# # TODO: use Out() + + # may be comments only + if len(style.seq) > 0: + if separator is None: + separator = self.prefs.lineSeparator + + if self.prefs.keepAllProperties: + # all + seq = style.seq + else: + # only effective ones + _effective = style.getProperties() + seq = [item for item in style.seq + if (isinstance(item.value, cssutils.css.Property) + and item.value in _effective) + or not isinstance(item.value, cssutils.css.Property)] + + out = [] + for i, item in enumerate(seq): + typ, val = item.type, item.value + if isinstance(val, cssutils.css.CSSComment): + # CSSComment + if self.prefs.keepComments: + out.append(val.cssText) + out.append(separator) + elif isinstance(val, cssutils.css.Property): + # PropertySimilarNameList + out.append(self.do_Property(val)) + if not (self.prefs.omitLastSemicolon and i==len(seq)-1): + out.append(u';') + out.append(separator) + elif isinstance(val, cssutils.css.CSSUnknownRule): + # @rule + out.append(val.cssText) + out.append(separator) + else: + # ? + out.append(val) + out.append(separator) + + if out and out[-1] == separator: + del out[-1] + + return u''.join(out) + + else: + return u'' + + def do_Property(self, property): + """ + Style declaration of CSSStyleRule + + Property has a seqs attribute which contains seq lists for + name, a CSSvalue and a seq list for priority + """ + # TODO: use Out() + + out = [] + if property.seqs[0] and property.wellformed and self._valid(property): + nameseq, cssvalue, priorityseq = property.seqs + + #name + for part in nameseq: + if hasattr(part, 'cssText'): + out.append(part.cssText) + elif property.literalname == part: + out.append(self._propertyname(property, part)) + else: + out.append(part) + + if out and (not property._mediaQuery or + property._mediaQuery and cssvalue.cssText): + # MediaQuery may consist of name only + out.append(u':') + out.append(self.prefs.propertyNameSpacer) + + # value + out.append(cssvalue.cssText) + + # priority + if out and priorityseq: + out.append(u' ') + for part in priorityseq: + if hasattr(part, 'cssText'): # comments + out.append(part.cssText) + else: + if part == property.literalpriority and\ + self.prefs.defaultPropertyPriority: + out.append(property.priority) + else: + out.append(part) + + return u''.join(out) + + def do_Property_priority(self, priorityseq): + """ + a Properties priority "!" S* "important" + """ + # TODO: use Out() + + out = [] + for part in priorityseq: + if hasattr(part, 'cssText'): # comments + out.append(u' ') + out.append(part.cssText) + out.append(u' ') + else: + out.append(part) + return u''.join(out).strip() + + def do_css_CSSValue(self, cssvalue): + """Serializes a CSSValue""" + # TODO: use self._valid(cssvalue)? + if not cssvalue: + return u'' + else: + out = Out(self) + for item in cssvalue.seq: + type_, val = item.type, item.value + if type_ in (cssutils.css.CSSColor, + cssutils.css.CSSValue): + # CSSColor or CSSValue if a CSSValueList + out.append(val.cssText, type_, space=False, keepS=True) + else: + if val and val[0] == val[-1] and val[0] in '\'"': + val = self._string(val[1:-1]) + # S must be kept! in between values but no extra space + out.append(val, type_, space=False, keepS=True) + return out.value() + + def do_css_CSSPrimitiveValue(self, cssvalue): + """Serialize a CSSPrimitiveValue""" + # TODO: use self._valid(cssvalue)? + if not cssvalue: + return u'' + else: + out = Out(self) + + unary = None + for item in cssvalue.seq: + type_, val = item.type, item.value + if 'CHAR' == type_ and val in u'+-': + # save for next round + unary = val + continue + if cssutils.css.CSSColor == type_: + # Comment or CSSColor + val = val.cssText + elif type_ in ('DIMENSION', 'NUMBER', 'PERCENTAGE'): + # handle saved unary and add to number + try: + # NUMBER or DIMENSION and is it 0? + if 0 == cssvalue.getFloatValue(): + val = u'0' + else: + # add unary to val if not 0 + # TODO: only for lengths! + if u'-' == unary: + val = unary + val + except xml.dom.InvalidAccessErr, e: + pass + unary = None + elif unary: + # or simple add + out.append(unary, 'CHAR', space=False, keepS=True) + unary = None + + out.append(val, type_) +# if hasattr(val, 'cssText'): +# # comments or CSSValue if a CSSValueList +# out.append(val.cssText, type_) +# else: +# out.append(val, type_) #? + + return out.value() + + def do_css_CSSColor(self, cssvalue): + """Serialize a CSSColor value""" + if not cssvalue: + return u'' + else: + out = Out(self) + unary = None + for item in cssvalue.seq: + type_, val = item.type, item.value + + # prepare + if 'HASH' == type_: + # TODO: add pref for this! + if len(val) == 7 and val[1] == val[2] and \ + val[3] == val[4] and val[5] == val[6]: + val = u'#%s%s%s' % (val[1], val[3], val[5]) + elif 'CHAR' == type_ and val in u'+-': + # save - for next round + if u'-' == val: + # omit + + unary = val + continue + elif unary: + val = unary + val.cssText + unary = None + + out.append(val, type_) + + return out.value() + + def do_stylesheets_medialist(self, medialist): + """ + comma-separated list of media, default is 'all' + + If "all" is in the list, every other media *except* "handheld" will + be stripped. This is because how Opera handles CSS for PDAs. + """ + if len(medialist) == 0: + return u'all' + else: + sep = u',%s' % self.prefs.listItemSpacer + return sep.join((mq.mediaText for mq in medialist)) + + def do_stylesheets_mediaquery(self, mediaquery): + """ + a single media used in medialist + """ + if mediaquery.wellformed: + out = [] + for part in mediaquery.seq: + if isinstance(part, cssutils.css.Property): # Property + out.append(u'(%s)' % part.cssText) + elif hasattr(part, 'cssText'): # comments + out.append(part.cssText) + else: + # TODO: media queries! + out.append(part) + return u' '.join(out) + else: + return u'' diff --git a/src/cssutils/stylesheets/__init__.py b/src/cssutils/stylesheets/__init__.py new file mode 100644 index 0000000000..07717fd40c --- /dev/null +++ b/src/cssutils/stylesheets/__init__.py @@ -0,0 +1,18 @@ +""" +Document Object Model Level 2 Style Sheets +http://www.w3.org/TR/2000/PR-DOM-Level-2-Style-20000927/stylesheets.html + +currently implemented: + - MediaList + - MediaQuery (http://www.w3.org/TR/css3-mediaqueries/) + - StyleSheet + - StyleSheetList +""" +__all__ = ['MediaList', 'MediaQuery', 'StyleSheet', 'StyleSheetList'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: __init__.py 1116 2008-03-05 13:52:23Z cthedot $' + +from medialist import * +from mediaquery import * +from stylesheet import * +from stylesheetlist import * diff --git a/src/cssutils/stylesheets/medialist.py b/src/cssutils/stylesheets/medialist.py new file mode 100644 index 0000000000..815071ae2c --- /dev/null +++ b/src/cssutils/stylesheets/medialist.py @@ -0,0 +1,256 @@ +""" +MediaList implements DOM Level 2 Style Sheets MediaList. + +TODO: + - delete: maybe if deleting from all, replace *all* with all others? + - is unknown media an exception? +""" +__all__ = ['MediaList'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: medialist.py 1423 2008-08-11 12:43:22Z cthedot $' + +import xml.dom +import cssutils +from cssutils.css import csscomment +from mediaquery import MediaQuery + +class MediaList(cssutils.util.Base, cssutils.util.ListSeq): + """ + Provides the abstraction of an ordered collection of media, + without defining or constraining how this collection is + implemented. + + A media is always an instance of MediaQuery. + + An empty list is the same as a list that contains the medium "all". + + Properties + ========== + length: + The number of MediaQuery objects in the list. + mediaText: of type DOMString + The parsable textual representation of this MediaList + self: a list (cssutils) + All MediaQueries in this MediaList + wellformed: + if this list is wellformed + + Format + ====== + :: + + medium [ COMMA S* medium ]* + + New:: + + <media_query> [, <media_query> ]* + """ + def __init__(self, mediaText=None, readonly=False): + """ + mediaText + unicodestring of parsable comma separared media + or a list of media + """ + super(MediaList, self).__init__() + self._wellformed = False + + if isinstance(mediaText, list): + mediaText = u','.join(mediaText) + + if mediaText: + self.mediaText = mediaText + + self._readonly = readonly + + length = property(lambda self: len(self), + doc="(DOM readonly) The number of media in the list.") + + def _getMediaText(self): + """ + returns serialized property mediaText + """ + return cssutils.ser.do_stylesheets_medialist(self) + + def _setMediaText(self, mediaText): + """ + mediaText + simple value or comma-separated list of media + + DOMException + + - SYNTAX_ERR: (MediaQuery) + Raised if the specified string value has a syntax error and is + unparsable. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this media list is readonly. + """ + self._checkReadonly() + wellformed = True + tokenizer = self._tokenize2(mediaText) + newseq = [] + + expected = None + while True: + # find all upto and including next ",", EOF or nothing + mqtokens = self._tokensupto2(tokenizer, listseponly=True) + if mqtokens: + if self._tokenvalue(mqtokens[-1]) == ',': + expected = mqtokens.pop() + else: + expected = None + + mq = MediaQuery(mqtokens) + if mq.wellformed: + newseq.append(mq) + else: + wellformed = False + self._log.error(u'MediaList: Invalid MediaQuery: %s' % + self._valuestr(mqtokens)) + else: + break + + # post condition + if expected: + wellformed = False + self._log.error(u'MediaList: Cannot end with ",".') + + if wellformed: + del self[:] + for mq in newseq: + self.appendMedium(mq) + self._wellformed = True + + mediaText = property(_getMediaText, _setMediaText, + doc="""(DOM) The parsable textual representation of the media list. + This is a comma-separated list of media.""") + + wellformed = property(lambda self: self._wellformed) + + def __prepareset(self, newMedium): + # used by appendSelector and __setitem__ + self._checkReadonly() + + if not isinstance(newMedium, MediaQuery): + newMedium = MediaQuery(newMedium) + + if newMedium.wellformed: + return newMedium + + def __setitem__(self, index, newMedium): + """ + overwrites ListSeq.__setitem__ + + Any duplicate items are **not** removed. + """ + newMedium = self.__prepareset(newMedium) + if newMedium: + self.seq[index] = newMedium + # TODO: remove duplicates? + + def appendMedium(self, newMedium): + """ + (DOM) + Adds the medium newMedium to the end of the list. If the newMedium + is already used, it is first removed. + + newMedium + a string or a MediaQuery object + + returns if newMedium is wellformed + + DOMException + + - INVALID_CHARACTER_ERR: (self) + If the medium contains characters that are invalid in the + underlying style language. + - INVALID_MODIFICATION_ERR (self) + If mediaText is "all" and a new medium is tried to be added. + Exception is "handheld" which is set in any case (Opera does handle + "all, handheld" special, this special case might be removed in the + future). + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this list is readonly. + """ + newMedium = self.__prepareset(newMedium) + + if newMedium: + mts = [self._normalize(mq.mediaType) for mq in self] + newmt = self._normalize(newMedium.mediaType) + + if newmt in mts: + self.deleteMedium(newmt) + self.seq.append(newMedium) + elif u'all' == newmt: + # remove all except handheld (Opera) + h = None + for mq in self: + if mq.mediaType == u'handheld': + h = mq + del self[:] + self.seq.append(newMedium) + if h: + self.append(h) + elif u'all' in mts: + if u'handheld' == newmt: + self.seq.append(newMedium) + self._log.warn(u'MediaList: Already specified "all" but still setting new medium: %r' % + newMedium, error=xml.dom.InvalidModificationErr, neverraise=True) + else: + self._log.warn(u'MediaList: Ignoring new medium %r as already specified "all" (set ``mediaText`` instead).' % + newMedium, error=xml.dom.InvalidModificationErr) + else: + self.seq.append(newMedium) + + return True + + else: + return False + + def append(self, newMedium): + "overwrites ListSeq.append" + self.appendMedium(newMedium) + + def deleteMedium(self, oldMedium): + """ + (DOM) + Deletes the medium indicated by oldMedium from the list. + + DOMException + + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this list is readonly. + - NOT_FOUND_ERR: (self) + Raised if oldMedium is not in the list. + """ + self._checkReadonly() + oldMedium = self._normalize(oldMedium) + + for i, mq in enumerate(self): + if self._normalize(mq.mediaType) == oldMedium: + del self[i] + break + else: + self._log.error(u'"%s" not in this MediaList' % oldMedium, + error=xml.dom.NotFoundErr) +# raise xml.dom.NotFoundErr( +# u'"%s" not in this MediaList' % oldMedium) + + def item(self, index): + """ + (DOM) + Returns the mediaType of the index'th element in the list. + If index is greater than or equal to the number of media in the + list, returns None. + """ + try: + return self[index].mediaType + except IndexError: + return None + + def __repr__(self): + return "cssutils.stylesheets.%s(mediaText=%r)" % ( + self.__class__.__name__, self.mediaText) + + def __str__(self): + return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % ( + self.__class__.__name__, self.mediaText, id(self)) diff --git a/src/cssutils/stylesheets/mediaquery.py b/src/cssutils/stylesheets/mediaquery.py new file mode 100644 index 0000000000..46841a1764 --- /dev/null +++ b/src/cssutils/stylesheets/mediaquery.py @@ -0,0 +1,237 @@ +""" +MediaQuery, see http://www.w3.org/TR/css3-mediaqueries/ + +A cssutils own implementation, not defined in official DOM + +TODO: + add possibility to + +part of a media_query_list: <media_query> [, <media_query> ]* +see stylesheets.MediaList +""" +__all__ = ['MediaQuery'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: mediaquery.py 1363 2008-07-13 18:14:26Z cthedot $' + +import re +import xml.dom +import cssutils + +class MediaQuery(cssutils.util.Base): + """ + A Media Query consists of a media type and one or more + expressions involving media features. + + Properties + ========== + mediaText: of type DOMString + The parsable textual representation of this MediaQuery + mediaType: of type DOMString + one of MEDIA_TYPES like e.g. 'print' + seq: a list (cssutils) + All parts of this MediaQuery including CSSComments + wellformed: + if this query is wellformed + + Format + ====== + :: + + media_query: [[only | not]? <media_type> [ and <expression> ]*] + | <expression> [ and <expression> ]* + expression: ( <media_feature> [: <value>]? ) + media_type: all | aural | braille | handheld | print | + projection | screen | tty | tv | embossed + media_feature: width | min-width | max-width + | height | min-height | max-height + | device-width | min-device-width | max-device-width + | device-height | min-device-height | max-device-height + | device-aspect-ratio | min-device-aspect-ratio | max-device-aspect-ratio + | color | min-color | max-color + | color-index | min-color-index | max-color-index + | monochrome | min-monochrome | max-monochrome + | resolution | min-resolution | max-resolution + | scan | grid + + """ + MEDIA_TYPES = [u'all', u'aural', u'braille', u'embossed', u'handheld', + u'print', u'projection', u'screen', u'tty', u'tv'] + + # From the HTML spec (see MediaQuery): + # "[...] character that isn't a US ASCII letter [a-zA-Z] (Unicode + # decimal 65-90, 97-122), digit [0-9] (Unicode hex 30-39), or hyphen (45)." + # so the following is a valid mediaType + __mediaTypeMatch = re.compile(ur'^[-a-zA-Z0-9]+$', re.U).match + + def __init__(self, mediaText=None, readonly=False): + """ + mediaText + unicodestring of parsable media + """ + super(MediaQuery, self).__init__() + + self.seq = [] + self._mediaType = u'' + if mediaText: + self.mediaText = mediaText # sets self._mediaType too + + self._readonly = readonly + + def _getMediaText(self): + """ + returns serialized property mediaText + """ + return cssutils.ser.do_stylesheets_mediaquery(self) + + def _setMediaText(self, mediaText): + """ + mediaText + a single media query string, e.g. "print and (min-width: 25cm)" + + DOMException + + - SYNTAX_ERR: (self) + Raised if the specified string value has a syntax error and is + unparsable. + - INVALID_CHARACTER_ERR: (self) + Raised if the given mediaType is unknown. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this media query is readonly. + """ + self._checkReadonly() + tokenizer = self._tokenize2(mediaText) + if not tokenizer: + self._log.error(u'MediaQuery: No MediaText given.') + else: + # for closures: must be a mutable + new = {'mediatype': None, + 'wellformed': True } + + def _ident_or_dim(expected, seq, token, tokenizer=None): + # only|not or mediatype or and + val = self._tokenvalue(token) + nval = self._normalize(val) + if expected.endswith('mediatype'): + if nval in (u'only', u'not'): + # only or not + seq.append(val) + return 'mediatype' + else: + # mediatype + new['mediatype'] = val + seq.append(val) + return 'and' + elif 'and' == nval and expected.startswith('and'): + seq.append(u'and') + return 'feature' + else: + new['wellformed'] = False + self._log.error( + u'MediaQuery: Unexpected syntax.', token=token) + return expected + + def _char(expected, seq, token, tokenizer=None): + # starting a feature which basically is a CSS Property + # but may simply be a property name too + val = self._tokenvalue(token) + if val == u'(' and expected == 'feature': + proptokens = self._tokensupto2( + tokenizer, funcendonly=True) + if proptokens and u')' == self._tokenvalue(proptokens[-1]): + proptokens.pop() + property = cssutils.css.Property(_mediaQuery=True) + property.cssText = proptokens + seq.append(property) + return 'and or EOF' + else: + new['wellformed'] = False + self._log.error( + u'MediaQuery: Unexpected syntax, expected "and" but found "%s".' % + val, token) + return expected + + # expected: only|not or mediatype, mediatype, feature, and + newseq = [] + wellformed, expected = self._parse(expected='only|not or mediatype', + seq=newseq, tokenizer=tokenizer, + productions={'IDENT': _ident_or_dim, # e.g. "print" + 'DIMENSION': _ident_or_dim, # e.g. "3d" + 'CHAR': _char}) + wellformed = wellformed and new['wellformed'] + + # post conditions + if not new['mediatype']: + wellformed = False + self._log.error(u'MediaQuery: No mediatype found: %s' % + self._valuestr(mediaText)) + + if wellformed: + # set + self.mediaType = new['mediatype'] + self.seq = newseq + + mediaText = property(_getMediaText, _setMediaText, + doc="""(DOM) The parsable textual representation of the media list. + This is a comma-separated list of media.""") + + def _getMediaType(self): + """ + returns serialized property mediaText + """ + return self._mediaType + + def _setMediaType(self, mediaType): + """ + mediaType + one of MEDIA_TYPES + + DOMException + + - SYNTAX_ERR: (self) + Raised if the specified string value has a syntax error and is + unparsable. + - INVALID_CHARACTER_ERR: (self) + Raised if the given mediaType is unknown. + - NO_MODIFICATION_ALLOWED_ERR: (self) + Raised if this media query is readonly. + """ + self._checkReadonly() + nmediaType = self._normalize(mediaType) + + if not MediaQuery.__mediaTypeMatch(nmediaType): + self._log.error( + u'MediaQuery: Syntax Error in media type "%s".' % mediaType, + error=xml.dom.SyntaxErr) + else: + if nmediaType not in MediaQuery.MEDIA_TYPES: + self._log.warn( + u'MediaQuery: Unknown media type "%s".' % mediaType, + error=xml.dom.InvalidCharacterErr) + return + + # set + self._mediaType = mediaType + + # update seq + for i, x in enumerate(self.seq): + if isinstance(x, basestring): + if self._normalize(x) in (u'only', u'not'): + continue + else: + self.seq[i] = mediaType + break + else: + self.seq.insert(0, mediaType) + + mediaType = property(_getMediaType, _setMediaType, + doc="""(DOM) media type (one of MediaQuery.MEDIA_TYPES) of this MediaQuery.""") + + wellformed = property(lambda self: bool(len(self.seq))) + + def __repr__(self): + return "cssutils.stylesheets.%s(mediaText=%r)" % ( + self.__class__.__name__, self.mediaText) + + def __str__(self): + return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % ( + self.__class__.__name__, self.mediaText, id(self)) diff --git a/src/cssutils/stylesheets/stylesheet.py b/src/cssutils/stylesheets/stylesheet.py new file mode 100644 index 0000000000..487c4f7948 --- /dev/null +++ b/src/cssutils/stylesheets/stylesheet.py @@ -0,0 +1,101 @@ +""" +StyleSheet implements DOM Level 2 Style Sheets StyleSheet. +""" +__all__ = ['StyleSheet'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: stylesheet.py 1284 2008-06-05 16:29:17Z cthedot $' + +import urlparse +import cssutils + +class StyleSheet(cssutils.util.Base2): + """ + The StyleSheet interface is the abstract base interface + for any type of style sheet. It represents a single style + sheet associated with a structured document. + + In HTML, the StyleSheet interface represents either an + external style sheet, included via the HTML LINK element, + or an inline STYLE element (-ch: also an @import stylesheet?). + + In XML, this interface represents + an external style sheet, included via a style sheet + processing instruction. + """ + def __init__(self, type='text/css', + href=None, + media=None, + title=u'', + disabled=None, + ownerNode=None, + parentStyleSheet=None): + """ + type: readonly + This specifies the style sheet language for this + style sheet. The style sheet language is specified + as a content type (e.g. "text/css"). The content + type is often specified in the ownerNode. Also see + the type attribute definition for the LINK element + in HTML 4.0, and the type pseudo-attribute for the + XML style sheet processing instruction. + href: readonly + If the style sheet is a linked style sheet, the value + of this attribute is its location. For inline style + sheets, the value of this attribute is None. See the + href attribute definition for the LINK element in HTML + 4.0, and the href pseudo-attribute for the XML style + sheet processing instruction. + media: of type MediaList, readonly + The intended destination media for style information. + The media is often specified in the ownerNode. If no + media has been specified, the MediaList will be empty. + See the media attribute definition for the LINK element + in HTML 4.0, and the media pseudo-attribute for the XML + style sheet processing instruction. Modifying the media + list may cause a change to the attribute disabled. + title: readonly + The advisory title. The title is often specified in + the ownerNode. See the title attribute definition for + the LINK element in HTML 4.0, and the title + pseudo-attribute for the XML style sheet processing + instruction. + disabled: False if the style sheet is applied to the + document. True if it is not. Modifying this attribute + may cause a new resolution of style for the document. + A stylesheet only applies if both an appropriate medium + definition is present and the disabled attribute is False. + So, if the media doesn't apply to the current user agent, + the disabled attribute is ignored. + ownerNode: of type Node, readonly + The node that associates this style sheet with the + document. For HTML, this may be the corresponding LINK + or STYLE element. For XML, it may be the linking + processing instruction. For style sheets that are + included by other style sheets, the value of this + attribute is None. + parentStyleSheet: of type StyleSheet, readonly + For style sheet languages that support the concept + of style sheet inclusion, this attribute represents + the including style sheet, if one exists. If the style + sheet is a top-level style sheet, or the style sheet + language does not support inclusion, the value of this + attribute is None. + """ + super(StyleSheet, self).__init__() + + self._href = href + self._ownerNode = ownerNode + self._parentStyleSheet = parentStyleSheet + self._type = type + + self.disabled = bool(disabled) + self.media = media + self.title = title + + href = property(lambda self: self._href) + + ownerNode = property(lambda self: self._ownerNode) + + parentStyleSheet = property(lambda self: self._parentStyleSheet) + + type = property(lambda self: self._type, doc=u'Default: "ext/css"') diff --git a/src/cssutils/stylesheets/stylesheetlist.py b/src/cssutils/stylesheets/stylesheetlist.py new file mode 100644 index 0000000000..f2428641ee --- /dev/null +++ b/src/cssutils/stylesheets/stylesheetlist.py @@ -0,0 +1,35 @@ +""" +StyleSheetList implements DOM Level 2 Style Sheets StyleSheetList. +""" +__all__ = ['StyleSheetList'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: stylesheetlist.py 1116 2008-03-05 13:52:23Z cthedot $' + +class StyleSheetList(list): + """ + Interface StyleSheetList (introduced in DOM Level 2) + + The StyleSheetList interface provides the abstraction of an ordered + collection of style sheets. + + The items in the StyleSheetList are accessible via an integral index, + starting from 0. + + This Python implementation is based on a standard Python list so e.g. + allows ``examplelist[index]`` usage. + """ + def item(self, index): + """ + Used to retrieve a style sheet by ordinal index. If index is + greater than or equal to the number of style sheets in the list, + this returns None. + """ + try: + return self[index] + except IndexError: + return None + + length = property(lambda self: len(self), + doc="""The number of StyleSheets in the list. The range of valid + child stylesheet indices is 0 to length-1 inclusive.""") + diff --git a/src/cssutils/tokenize2.py b/src/cssutils/tokenize2.py new file mode 100644 index 0000000000..24607305bc --- /dev/null +++ b/src/cssutils/tokenize2.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""New CSS Tokenizer (a generator) +""" +__all__ = ['Tokenizer', 'CSSProductions'] +__docformat__ = 'restructuredtext' +__version__ = '$Id: tokenize2.py 1420 2008-08-09 19:28:34Z cthedot $' + +import re +from helper import normalize +from cssproductions import * + +class Tokenizer(object): + """ + generates a list of Token tuples: + (Tokenname, value, startline, startcolumn) + """ + _atkeywords = { + u'@font-face': CSSProductions.FONT_FACE_SYM, + u'@import': CSSProductions.IMPORT_SYM, + u'@media': CSSProductions.MEDIA_SYM, + u'@namespace': CSSProductions.NAMESPACE_SYM, + u'@page': CSSProductions.PAGE_SYM + } + _linesep = u'\n' + + def __init__(self, macros=None, productions=None): + """ + inits tokenizer with given macros and productions which default to + cssutils own macros and productions + """ + if not macros: + macros = MACROS + if not productions: + productions = PRODUCTIONS + self.tokenmatches = self._compile_productions( + self._expand_macros(macros, + productions)) + self.commentmatcher = [x[1] for x in self.tokenmatches if x[0] == 'COMMENT'][0] + self.urimatcher = [x[1] for x in self.tokenmatches if x[0] == 'URI'][0] + self.unicodesub = re.compile(r'\\[0-9a-fA-F]{1,6}(?:\r\n|[\t|\r|\n|\f|\x20])?').sub + + def _expand_macros(self, macros, productions): + """returns macro expanded productions, order of productions is kept""" + def macro_value(m): + return '(?:%s)' % macros[m.groupdict()['macro']] + expanded = [] + for key, value in productions: + while re.search(r'{[a-zA-Z][a-zA-Z0-9-]*}', value): + value = re.sub(r'{(?P<macro>[a-zA-Z][a-zA-Z0-9-]*)}', + macro_value, value) + expanded.append((key, value)) + return expanded + + def _compile_productions(self, expanded_productions): + """compile productions into callable match objects, order is kept""" + compiled = [] + for key, value in expanded_productions: + compiled.append((key, re.compile('^(?:%s)' % value, re.U).match)) + return compiled + + def tokenize(self, text, fullsheet=False): + """Generator: Tokenize text and yield tokens, each token is a tuple + of:: + + (nname, value, line, col) + + The token value will contain a normal string, meaning CSS unicode + escapes have been resolved to normal characters. The serializer + escapes needed characters back to unicode escapes depending on + the stylesheet target encoding. + + text + to be tokenized + fullsheet + if ``True`` appends EOF token as last one and completes incomplete + COMMENT or INVALID (to STRING) tokens + """ + def _repl(m): + "used by unicodesub" + num = int(m.group(0)[1:], 16) + if num < 0x10000: + return unichr(num) + else: + return m.group(0) + + def _normalize(value): + "normalize and do unicodesub" + return normalize(self.unicodesub(_repl, value)) + + line = col = 1 + + # check for BOM first as it should only be max one at the start + (BOM, matcher), productions = self.tokenmatches[0], self.tokenmatches[1:] + match = matcher(text) + if match: + found = match.group(0) + yield (BOM, found, line, col) + text = text[len(found):] + + # check for @charset which is valid only at start of CSS + if text.startswith('@charset '): + found = '@charset ' # production has trailing S! + yield (CSSProductions.CHARSET_SYM, found, line, col) + text = text[len(found):] + col += len(found) + + while text: + # speed test for most used CHARs + c = text[0] + if c in '{}:;,': + yield ('CHAR', c, line, col) + col += 1 + text = text[1:] + + else: + # check all other productions, at least CHAR must match + for name, matcher in productions: + if fullsheet and name == 'CHAR' and text.startswith(u'/*'): + # before CHAR production test for incomplete comment + possiblecomment = u'%s*/' % text + match = self.commentmatcher(possiblecomment) + if match: + yield ('COMMENT', possiblecomment, line, col) + text = None # eats all remaining text + break + + match = matcher(text) # if no match try next production + if match: + found = match.group(0) # needed later for line/col + if fullsheet: + # check if found may be completed into a full token + if 'INVALID' == name and text == found: + # complete INVALID to STRING with start char " or ' + name, found = 'STRING', '%s%s' % (found, found[0]) + + elif 'FUNCTION' == name and\ + u'url(' == _normalize(found): + # FUNCTION url( is fixed to URI if fullsheet + # FUNCTION production MUST BE after URI production! + for end in (u"')", u'")', u')'): + possibleuri = '%s%s' % (text, end) + match = self.urimatcher(possibleuri) + if match: + name, found = 'URI', match.group(0) + break + + if name in ('DIMENSION', 'IDENT', 'STRING', 'URI', + 'HASH', 'COMMENT', 'FUNCTION', 'INVALID'): + # may contain unicode escape, replace with normal char + # but do not _normalize (?) + value = self.unicodesub(_repl, found) + + else: + if 'ATKEYWORD' == name: + # get actual ATKEYWORD SYM + if '@charset' == found and ' ' == text[len(found):len(found)+1]: + # only this syntax! + name = CSSProductions.CHARSET_SYM + found += ' ' + else: + name = self._atkeywords.get(_normalize(found), 'ATKEYWORD') + + value = found # should not contain unicode escape (?) + + yield (name, value, line, col) + text = text[len(found):] + nls = found.count(self._linesep) + line += nls + if nls: + col = len(found[found.rfind(self._linesep):]) + else: + col += len(found) + break + + if fullsheet: + yield ('EOF', u'', line, col) diff --git a/src/cssutils/util.py b/src/cssutils/util.py new file mode 100644 index 0000000000..f2845de590 --- /dev/null +++ b/src/cssutils/util.py @@ -0,0 +1,853 @@ +"""base classes and helper functions for css and stylesheets packages +""" +__all__ = [] +__docformat__ = 'restructuredtext' +__version__ = '$Id: util.py 1453 2008-09-08 20:57:19Z cthedot $' + +import codecs +from itertools import ifilter +import types +import urllib2 +import xml.dom + +from helper import normalize +import tokenize2 +import cssutils +import encutils + +class Base(object): + """ + Base class for most CSS and StyleSheets classes + + **Superceded by Base2 which is used for new seq handling class.** + See cssutils.util.Base2 + + Contains helper methods for inheriting classes helping parsing + + ``_normalize`` is static as used by Preferences. + """ + __tokenizer2 = tokenize2.Tokenizer() + + _log = cssutils.log + _prods = tokenize2.CSSProductions + + # for more on shorthand properties see + # http://www.dustindiaz.com/css-shorthand/ + # format: shorthand: [(propname, mandatorycheck?)*] + _SHORTHANDPROPERTIES = { + u'background': [], + u'background-position': [], + u'border': [], + u'border-left': [], + u'border-right': [], + u'border-top': [], + u'border-bottom': [], + #u'border-color': [], # list or single but same values + #u'border-style': [], # list or single but same values + #u'border-width': [], # list or single but same values + u'cue': [], + u'font': [], + u'list-style': [], + #u'margin': [], # list or single but same values + u'outline': [], + #u'padding': [], # list or single but same values + u'pause': [] + } + + @staticmethod + def _normalize(x): + """ + normalizes x, namely: + + - remove any \ before non unicode sequences (0-9a-zA-Z) so for + x=="c\olor\" return "color" (unicode escape sequences should have + been resolved by the tokenizer already) + - lowercase + """ + return normalize(x) + + def _checkReadonly(self): + "raises xml.dom.NoModificationAllowedErr if rule/... is readonly" + if hasattr(self, '_readonly') and self._readonly: + raise xml.dom.NoModificationAllowedErr( + u'%s is readonly.' % self.__class__) + return True + return False + + def _splitNamespacesOff(self, text_namespaces_tuple): + """ + returns tuple (text, dict-of-namespaces) or if no namespaces are + in cssText returns (cssText, {}) + + used in Selector, SelectorList, CSSStyleRule, CSSMediaRule and + CSSStyleSheet + """ + if isinstance(text_namespaces_tuple, tuple): + return text_namespaces_tuple[0], _SimpleNamespaces(self._log, + text_namespaces_tuple[1]) + else: + return text_namespaces_tuple, _SimpleNamespaces(log=self._log) + + def _tokenize2(self, textortokens): + """ + returns tokens of textortokens which may already be tokens in which + case simply returns input + """ + if not textortokens: + return None + elif isinstance(textortokens, basestring): + # needs to be tokenized + return self.__tokenizer2.tokenize( + textortokens) + elif types.GeneratorType == type(textortokens): + # already tokenized + return textortokens + elif isinstance(textortokens, tuple): + # a single token (like a comment) + return [textortokens] + else: + # already tokenized but return generator + return (x for x in textortokens) + + def _nexttoken(self, tokenizer, default=None): + "returns next token in generator tokenizer or the default value" + try: + return tokenizer.next() + except (StopIteration, AttributeError): + return default + + def _type(self, token): + "returns type of Tokenizer token" + if token: + return token[0] + else: + return None + + def _tokenvalue(self, token, normalize=False): + "returns value of Tokenizer token" + if token and normalize: + return Base._normalize(token[1]) + elif token: + return token[1] + else: + return None + + def _stringtokenvalue(self, token): + """ + for STRING returns the actual content without surrounding "" or '' + and without respective escapes, e.g.:: + + "with \" char" => with " char + """ + if token: + value = token[1] + return value.replace('\\'+value[0], value[0])[1:-1] + else: + return None + + def _uritokenvalue(self, token): + """ + for URI returns the actual content without surrounding url() + or url(""), url('') and without respective escapes, e.g.:: + + url("\"") => " + """ + if token: + value = token[1][4:-1].strip() + if value and (value[0] in '\'"') and (value[0] == value[-1]): + # a string "..." or '...' + value = value.replace('\\'+value[0], value[0])[1:-1] + return value + else: + return None + + def _tokensupto2(self, + tokenizer, + starttoken=None, + blockstartonly=False, # { + blockendonly=False, # } + mediaendonly=False, + importmediaqueryendonly=False, # ; or STRING + mediaqueryendonly=False, # { or STRING + semicolon=False, # ; + propertynameendonly=False, # : + propertyvalueendonly=False, # ! ; } + propertypriorityendonly=False, # ; } + selectorattendonly=False, # ] + funcendonly=False, # ) + listseponly=False, # , + separateEnd=False # returns (resulttokens, endtoken) + ): + """ + returns tokens upto end of atrule and end index + end is defined by parameters, might be ; } ) or other + + default looks for ending "}" and ";" + """ + ends = u';}' + endtypes = () + brace = bracket = parant = 0 # {}, [], () + + if blockstartonly: # { + ends = u'{' + brace = -1 # set to 0 with first { + elif blockendonly: # } + ends = u'}' + brace = 1 + elif mediaendonly: # } + ends = u'}' + brace = 1 # rules } and mediarules } + elif importmediaqueryendonly: + # end of mediaquery which may be ; or STRING + ends = u';' + endtypes = ('STRING',) + elif mediaqueryendonly: + # end of mediaquery which may be { or STRING + # special case, see below + ends = u'{' + brace = -1 # set to 0 with first { + endtypes = ('STRING',) + elif semicolon: + ends = u';' + elif propertynameendonly: # : and ; in case of an error + ends = u':;' + elif propertyvalueendonly: # ; or !important + ends = u';!' + elif propertypriorityendonly: # ; + ends = u';' + elif selectorattendonly: # ] + ends = u']' + if starttoken and self._tokenvalue(starttoken) == u'[': + bracket = 1 + elif funcendonly: # ) + ends = u')' + parant = 1 + elif listseponly: # , + ends = u',' + + resulttokens = [] + if starttoken: + resulttokens.append(starttoken) + if tokenizer: + for token in tokenizer: + typ, val, line, col = token + if 'EOF' == typ: + resulttokens.append(token) + break + if u'{' == val: + brace += 1 + elif u'}' == val: + brace -= 1 + elif u'[' == val: + bracket += 1 + elif u']' == val: + bracket -= 1 + # function( or single ( + elif u'(' == val or \ + Base._prods.FUNCTION == typ: + parant += 1 + elif u')' == val: + parant -= 1 + + resulttokens.append(token) + + if (brace == bracket == parant == 0) and ( + val in ends or typ in endtypes): + break + elif mediaqueryendonly and brace == -1 and ( + bracket == parant == 0) and typ in endtypes: + # mediaqueryendonly with STRING + break + + if separateEnd: + # TODO: use this method as generator, then this makes sense + if resulttokens: + return resulttokens[:-1], resulttokens[-1] + else: + return resulttokens, None + else: + return resulttokens + + def _valuestr(self, t): + """ + returns string value of t (t may be a string, a list of token tuples + or a single tuple in format (type, value, line, col). + Mainly used to get a string value of t for error messages. + """ + if not t: + return u'' + elif isinstance(t, basestring): + return t + else: + return u''.join([x[1] for x in t]) + + def _adddefaultproductions(self, productions, new=None): + """ + adds default productions if not already present, used by + _parse only + + each production should return the next expected token + normaly a name like "uri" or "EOF" + some have no expectation like S or COMMENT, so simply return + the current value of self.__expected + """ + def ATKEYWORD(expected, seq, token, tokenizer=None): + "default impl for unexpected @rule" + if expected != 'EOF': + # TODO: parentStyleSheet=self + rule = cssutils.css.CSSUnknownRule() + rule.cssText = self._tokensupto2(tokenizer, token) + if rule.wellformed: + seq.append(rule) + return expected + else: + new['wellformed'] = False + self._log.error(u'Expected EOF.', token=token) + return expected + + def COMMENT(expected, seq, token, tokenizer=None): + "default implementation for COMMENT token adds CSSCommentRule" + seq.append(cssutils.css.CSSComment([token])) + return expected + + def S(expected, seq, token, tokenizer=None): + "default implementation for S token, does nothing" + return expected + + def EOF(expected=None, seq=None, token=None, tokenizer=None): + "default implementation for EOF token" + return 'EOF' + + p = {'ATKEYWORD': ATKEYWORD, + 'COMMENT': COMMENT, + 'S': S, + 'EOF': EOF # only available if fullsheet + } + p.update(productions) + return p + + def _parse(self, expected, seq, tokenizer, productions, default=None, + new=None, initialtoken=None): + """ + puts parsed tokens in seq by calling a production with + (seq, tokenizer, token) + + expected + a name what token or value is expected next, e.g. 'uri' + seq + to add rules etc to + tokenizer + call tokenizer.next() to get next token + productions + callbacks {tokentype: callback} + default + default callback if tokentype not in productions + new + used to init default productions + initialtoken + will be used together with tokenizer running 1st this token + and then all tokens in tokenizer + + returns (wellformed, expected) which the last prod might have set + """ + wellformed = True + + if initialtoken: + # add initialtoken to tokenizer + def tokens(): + "Build new tokenizer including initialtoken" + yield initialtoken + for item in tokenizer: + yield item + fulltokenizer = (t for t in tokens()) + else: + fulltokenizer = tokenizer + + if fulltokenizer: + prods = self._adddefaultproductions(productions, new) + for token in fulltokenizer: + p = prods.get(token[0], default) + if p: + expected = p(expected, seq, token, tokenizer) + else: + wellformed = False + self._log.error(u'Unexpected token (%s, %s, %s, %s)' % token) + return wellformed, expected + + +class Base2(Base): + """ + Base class for new seq handling, used by Selector for now only + """ + def __init__(self): + self._seq = Seq() + + def _setSeq(self, newseq): + """ + sets newseq and makes it readonly + """ + newseq._readonly = True + self._seq = newseq + + seq = property(lambda self: self._seq, doc="seq for most classes") + + def _tempSeq(self, readonly=False): + "get a writeable Seq() which is added later" + return Seq(readonly=readonly) + + def _adddefaultproductions(self, productions, new=None): + """ + adds default productions if not already present, used by + _parse only + + each production should return the next expected token + normaly a name like "uri" or "EOF" + some have no expectation like S or COMMENT, so simply return + the current value of self.__expected + """ + def ATKEYWORD(expected, seq, token, tokenizer=None): + "default impl for unexpected @rule" + if expected != 'EOF': + # TODO: parentStyleSheet=self + rule = cssutils.css.CSSUnknownRule() + rule.cssText = self._tokensupto2(tokenizer, token) + if rule.wellformed: + seq.append(rule, cssutils.css.CSSRule.UNKNOWN_RULE, + line=token[2], col=token[3]) + return expected + else: + new['wellformed'] = False + self._log.error(u'Expected EOF.', token=token) + return expected + + def COMMENT(expected, seq, token, tokenizer=None): + "default impl, adds CSSCommentRule if not token == EOF" + if expected == 'EOF': + new['wellformed'] = False + self._log.error(u'Expected EOF but found comment.', token=token) + seq.append(cssutils.css.CSSComment([token]), 'COMMENT') + return expected + + def S(expected, seq, token, tokenizer=None): + "default impl, does nothing if not token == EOF" + if expected == 'EOF': + new['wellformed'] = False + self._log.error(u'Expected EOF but found whitespace.', token=token) + return expected + + def EOF(expected=None, seq=None, token=None, tokenizer=None): + "default implementation for EOF token" + return 'EOF' + + defaultproductions = {'ATKEYWORD': ATKEYWORD, + 'COMMENT': COMMENT, + 'S': S, + 'EOF': EOF # only available if fullsheet + } + defaultproductions.update(productions) + return defaultproductions + + +class Seq(object): + """ + property seq of Base2 inheriting classes, holds a list of Item objects. + + used only by Selector for now + + is normally readonly, only writable during parsing + """ + def __init__(self, readonly=True): + """ + only way to write to a Seq is to initialize it with new items + each itemtuple has (value, type, line) where line is optional + """ + self._seq = [] + self._readonly = readonly + + def __delitem__(self, i): + del self._seq[i] + + def __getitem__(self, i): + return self._seq[i] + + def __setitem__(self, i, (val, typ, line, col)): + self._seq[i] = Item(val, typ, line, col) + + def __iter__(self): + return iter(self._seq) + + def __len__(self): + return len(self._seq) + + def append(self, val, typ, line=None, col=None): + "if not readonly add new Item()" + if self._readonly: + raise AttributeError('Seq is readonly.') + else: + self._seq.append(Item(val, typ, line, col)) + + def appendItem(self, item): + "if not readonly add item which must be an Item" + if self._readonly: + raise AttributeError('Seq is readonly.') + else: + self._seq.append(item) + + def replace(self, index=-1, val=None, typ=None, line=None, col=None): + """ + if not readonly replace Item at index with new Item or + simply replace value or type + """ + if self._readonly: + raise AttributeError('Seq is readonly.') + else: + self._seq[index] = Item(val, typ, line, col) + + def appendToVal(self, val=None, index=-1): + """ + if not readonly append to Item's value at index + """ + if self._readonly: + raise AttributeError('Seq is readonly.') + else: + old = self._seq[index] + self._seq[index] = Item(old.value + val, old.type, + old.line, old.col) + + def __repr__(self): + "returns a repr same as a list of tuples of (value, type)" + return u'cssutils.%s.%s([\n %s])' % (self.__module__, + self.__class__.__name__, + u',\n '.join([u'%r' % item for item in self._seq] + )) + def __str__(self): + vals = [] + for v in self: + if isinstance(v.value, basestring): + vals.append(v.value) + elif type(v) == tuple: + vals.append(v.value[1]) + else: + vals.append(str(v)) + + return "<cssutils.%s.%s object length=%r valuestring=%r at 0x%x>" % ( + self.__module__, self.__class__.__name__, len(self), + u''.join(vals), id(self)) + +class Item(object): + """ + an item in the seq list of classes (successor to tuple items in old seq) + + each item has attributes: + + type + a sematic type like "element", "attribute" + value + the actual value which may be a string, number etc or an instance + of e.g. a CSSComment + *line* + **NOT IMPLEMENTED YET, may contain the line in the source later** + """ + def __init__(self, value, type, line=None, col=None): + self.__value = value + self.__type = type + self.__line = line + self.__col = col + + type = property(lambda self: self.__type) + value = property(lambda self: self.__value) + line = property(lambda self: self.__line) + col = property(lambda self: self.__col) + + def __repr__(self): + return "%s.%s(value=%r, type=%r, line=%r, col=%r)" % ( + self.__module__, self.__class__.__name__, + self.__value, self.__type, self.__line, self.__col) + + +class ListSeq(object): + """ + (EXPERIMENTAL) + A base class used for list classes like css.SelectorList or + stylesheets.MediaList + + adds list like behaviour running on inhering class' property ``seq`` + + - item in x => bool + - len(x) => integer + - get, set and del x[i] + - for item in x + - append(item) + + some methods must be overwritten in inheriting class + """ + def __init__(self): + self.seq = [] # does not need to use ``Seq`` as simple list only + + def __contains__(self, item): + return item in self.seq + + def __delitem__(self, index): + del self.seq[index] + + def __getitem__(self, index): + return self.seq[index] + + def __iter__(self): + def gen(): + for x in self.seq: + yield x + return gen() + + def __len__(self): + return len(self.seq) + + def __setitem__(self, index, item): + "must be overwritten" + raise NotImplementedError + + def append(self, item): + "must be overwritten" + raise NotImplementedError + + +class _Namespaces(object): + """ + A dictionary like wrapper for @namespace rules used in a CSSStyleSheet. + Works on effective namespaces, so e.g. if:: + + @namespace p1 "uri"; + @namespace p2 "uri"; + + only the second rule is effective and kept. + + namespaces + a dictionary {prefix: namespaceURI} containing the effective namespaces + only. These are the latest set in the CSSStyleSheet. + parentStyleSheet + the parent CSSStyleSheet + """ + def __init__(self, parentStyleSheet, log=None, *args): + "no initial values are set, only the relevant sheet is" + self.parentStyleSheet = parentStyleSheet + self._log = log + + def __contains__(self, prefix): + return prefix in self.namespaces + + def __delitem__(self, prefix): + """deletes CSSNamespaceRule(s) with rule.prefix == prefix + + prefix '' and None are handled the same + """ + if not prefix: + prefix = u'' + delrule = self.__findrule(prefix) + for i, rule in enumerate(ifilter(lambda r: r.type == r.NAMESPACE_RULE, + self.parentStyleSheet.cssRules)): + if rule == delrule: + self.parentStyleSheet.deleteRule(i) + return + + self._log.error('Prefix %r not found.' % prefix, + error=xml.dom.NamespaceErr) + + def __getitem__(self, prefix): + try: + return self.namespaces[prefix] + except KeyError, e: + self._log.error('Prefix %r not found.' % prefix, + error=xml.dom.NamespaceErr) + + def __iter__(self): + return self.namespaces.__iter__() + + def __len__(self): + return len(self.namespaces) + + def __setitem__(self, prefix, namespaceURI): + "replaces prefix or sets new rule, may raise NoModificationAllowedErr" + if not prefix: + prefix = u'' # None or '' + rule = self.__findrule(prefix) + if not rule: + self.parentStyleSheet.insertRule(cssutils.css.CSSNamespaceRule( + prefix=prefix, + namespaceURI=namespaceURI), + inOrder=True) + else: + if prefix in self.namespaces: + rule.namespaceURI = namespaceURI # raises NoModificationAllowedErr + if namespaceURI in self.namespaces.values(): + rule.prefix = prefix + + def __findrule(self, prefix): + # returns namespace rule where prefix == key + for rule in ifilter(lambda r: r.type == r.NAMESPACE_RULE, + reversed(self.parentStyleSheet.cssRules)): + if rule.prefix == prefix: + return rule + + def __getNamespaces(self): + namespaces = {} + for rule in ifilter(lambda r: r.type == r.NAMESPACE_RULE, + reversed(self.parentStyleSheet.cssRules)): + if rule.namespaceURI not in namespaces.values(): + namespaces[rule.prefix] = rule.namespaceURI + return namespaces + + namespaces = property(__getNamespaces, + doc=u'Holds only effective @namespace rules in self.parentStyleSheets' + '@namespace rules.') + + def get(self, prefix, default): + return self.namespaces.get(prefix, default) + + def items(self): + return self.namespaces.items() + + def keys(self): + return self.namespaces.keys() + + def values(self): + return self.namespaces.values() + + def prefixForNamespaceURI(self, namespaceURI): + """ + returns effective prefix for given namespaceURI or raises IndexError + if this cannot be found""" + for prefix, uri in self.namespaces.items(): + if uri == namespaceURI: + return prefix + raise IndexError(u'NamespaceURI %r not found.' % namespaceURI) + + def __str__(self): + return u"<cssutils.util.%s object parentStyleSheet=%r at 0x%x>" % ( + self.__class__.__name__, str(self.parentStyleSheet), id(self)) + + +class _SimpleNamespaces(_Namespaces): + """ + namespaces used in objects like Selector as long as they are not connected + to a CSSStyleSheet + """ + def __init__(self, log=None, *args): + """init""" + super(_SimpleNamespaces, self).__init__(parentStyleSheet=None, log=log) + self.__namespaces = dict(*args) + + def __setitem__(self, prefix, namespaceURI): + self.__namespaces[prefix] = namespaceURI + + namespaces = property(lambda self: self.__namespaces, + doc=u'Dict Wrapper for self.sheets @namespace rules.') + + def __str__(self): + return u"<cssutils.util.%s object namespaces=%r at 0x%x>" % ( + self.__class__.__name__, self.namespaces, id(self)) + + def __repr__(self): + return u"cssutils.util.%s(%r)" % (self.__class__.__name__, + self.namespaces) + + +def _defaultFetcher(url): + """Retrieve data from ``url``. cssutils default implementation of fetch + URL function. + + Returns ``(encoding, string)`` or ``None`` + """ + try: + res = urllib2.urlopen(url) + except OSError, e: + # e.g if file URL and not found + cssutils.log.warn(e, error=OSError) + except (OSError, ValueError), e: + # invalid url, e.g. "1" + cssutils.log.warn(u'ValueError, %s' % e.message, error=ValueError) + except urllib2.HTTPError, e: + # http error, e.g. 404, e can be raised + cssutils.log.warn(u'HTTPError opening url=%r: %s %s' % + (url, e.code, e.msg), error=e) + except urllib2.URLError, e: + # URLError like mailto: or other IO errors, e can be raised + cssutils.log.warn(u'URLError, %s' % e.reason, error=e) + else: + if res: + mimeType, encoding = encutils.getHTTPInfo(res) + if mimeType != u'text/css': + cssutils.log.error(u'Expected "text/css" mime type for url=%r but found: %r' % + (url, mimeType), error=ValueError) + return encoding, res.read() + +def _readUrl(url, fetcher=None, overrideEncoding=None, parentEncoding=None): + """ + Read cssText from url and decode it using all relevant methods (HTTP + header, BOM, @charset). Returns + + - encoding used to decode text (which is needed to set encoding of + stylesheet properly) + - type of encoding (how it was retrieved, see list below) + - decodedCssText + + ``fetcher`` + see cssutils.registerFetchUrl for details + ``overrideEncoding`` + If given this encoding is used and all other encoding information is + ignored (HTTP, BOM etc) + ``parentEncoding`` + Encoding of parent stylesheet (while e.g. reading @import references sheets) + or document if available. + + Priority or encoding information + -------------------------------- + **cssutils only**: 0. overrideEncoding + + 1. An HTTP "charset" parameter in a "Content-Type" field (or similar parameters in other protocols) + 2. BOM and/or @charset (see below) + 3. <link charset=""> or other metadata from the linking mechanism (if any) + 4. charset of referring style sheet or document (if any) + 5. Assume UTF-8 + + """ + enctype = None + + if not fetcher: + fetcher = _defaultFetcher + r = fetcher(url) + if r and len(r) == 2 and r[1] is not None: + httpEncoding, content = r + + if overrideEncoding: + enctype = 0 # 0. override encoding + encoding = overrideEncoding + elif httpEncoding: + enctype = 1 # 1. HTTP + encoding = httpEncoding + else: + # check content + contentEncoding, explicit = cssutils.codec.detectencoding_str(content) + if explicit: + enctype = 2 # 2. BOM/@charset: explicitly + encoding = contentEncoding + elif parentEncoding: + enctype = 4 # 4. parent stylesheet or document + # may also be None in which case 5. is used in next step anyway + encoding = parentEncoding + else: + enctype = 5 # 5. assume UTF-8 + encoding = 'utf-8' + + try: + # encoding may still be wrong if encoding *is lying*! + if content is not None: + decodedCssText = codecs.lookup("css")[1](content, encoding=encoding)[0] + else: + decodedCssText = None + except UnicodeDecodeError, e: + cssutils.log.warn(e, neverraise=True) + decodedCssText = None + + return encoding, enctype, decodedCssText + else: + return None, None, None diff --git a/src/encutils/__init__.py b/src/encutils/__init__.py new file mode 100644 index 0000000000..f2eb4eefb3 --- /dev/null +++ b/src/encutils/__init__.py @@ -0,0 +1,655 @@ +#!/usr/bin/env python +"""encutils - encoding detection collection for Python + +encutils +======== +:Author: Christof Hoeke, see http://cthedot.de/encutils/ +:Copyright: 2005-2008: Christof Hoeke +:License: encutils has a dual-license, please choose whatever you prefer: + + * encutils is published under the `LGPL 3 or later <http://cthedot.de/encutils/license/>`__ + * encutils is published under the + `Creative Commons License <http://creativecommons.org/licenses/by/3.0/>`__. + + This file is part of encutils. + + encutils is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + encutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with encutils. If not, see <http://www.gnu.org/licenses/>. + + +A collection of helper functions to detect encodings of text files (like HTML, XHTML, XML, CSS, etc.) retrieved via HTTP, file or string. + +``getEncodingInfo`` is probably the main function of interest which uses +other supplied functions itself and gathers all information together and +supplies an ``EncodingInfo`` object with the following properties: + +- ``encoding``: The guessed encoding + Encoding is the explicit or implicit encoding or None and + always lowercase. + +- from HTTP response + * ``http_encoding`` + * ``http_media_type`` + +- from HTML <meta> element + * ``meta_encoding`` + * ``meta_media_type`` + +- from XML declaration + * ``xml_encoding`` + +example:: + + >>> import encutils + >>> info = encutils.getEncodingInfo(url='http://cthedot.de/encutils/') + + >>> print info # = str(info) + utf-8 + + >>> info # = repr(info) + <encutils.EncodingInfo object encoding='utf-8' mismatch=False at 0xb86d30> + + >>> print info.logtext + HTTP media_type: text/html + HTTP encoding: utf-8 + HTML META media_type: text/html + HTML META encoding: utf-8 + Encoding (probably): utf-8 (Mismatch: False) + + +references +========== +XML + RFC 3023 (http://www.ietf.org/rfc/rfc3023.txt) + + easier explained in + - http://feedparser.org/docs/advanced.html + - http://www.xml.com/pub/a/2004/07/21/dive.html + +HTML + http://www.w3.org/TR/REC-html40/charset.html#h-5.2.2 + +TODO +==== +- parse @charset of HTML elements? +- check for more texttypes if only text given + +""" +__all__ = ['buildlog', + 'encodingByMediaType', + 'getHTTPInfo', + 'getMetaInfo', + 'detectXMLEncoding', + 'getEncodingInfo', + 'tryEncodings', + 'EncodingInfo'] +__docformat__ = 'restructuredtext' +__author__ = 'Christof Hoeke' +__version__ = '0.8.3 $Id: __init__.py 1138 2008-03-15 18:24:46Z cthedot $' + +import cgi +import HTMLParser +import httplib +import re +import StringIO +import sys +import types +import urllib + +class _MetaHTMLParser(HTMLParser.HTMLParser): + """parses given data for <meta http-equiv="content-type">""" + content_type = None + + def handle_starttag(self, tag, attrs): + if tag == 'meta' and not self.content_type: + atts = dict([(a.lower(), v.lower()) for a, v in attrs]) + if atts.get('http-equiv', u'').strip() == u'content-type': + self.content_type = atts.get('content') + + +# application/xml, application/xml-dtd, application/xml-external-parsed-entity, or a subtype like application/rss+xml. +_XML_APPLICATION_TYPE = 0 + +# text/xml, text/xml-external-parsed-entity, or a subtype like text/AnythingAtAll+xml +_XML_TEXT_TYPE = 1 + +# text/html +_HTML_TEXT_TYPE = 2 + +# any other of text/* like text/plain, ... +_TEXT_TYPE = 3 + +# any text/* like which defaults to UTF-8 encoding, for now only text/css +_TEXT_UTF8 = 5 + +# types not fitting in above types +_OTHER_TYPE = 4 + +class EncodingInfo(object): + """ + All encoding related information, returned by ``getEncodingInfo`` + + - ``encoding``: The guessed encoding + Encoding is the explicit or implicit encoding or None and + always lowercase. + + - from HTTP response + * ``http_encoding`` + * ``http_media_type`` + + - from HTML <meta> element + * ``meta_encoding`` + * ``meta_media_type`` + + - from XML declaration + * ``xml_encoding`` + + - ``mismatch``: True if mismatch between XML declaration and HTTP header + Mismatch is True if any mismatches between HTTP header, XML + declaration or textcontent (meta) are found. More detailed mismatch + reports are written to the optional log or ``logtext`` + + Mismatches are not necessarily errors as preferences are defined. + For details see the specifications. + + - ``logtext``: if no log was given log reports are given here + + """ + def __init__(self): + """ + initializes all possible properties to ``None``, see class + description + """ + self.encoding = self.mismatch = self.logtext =\ + self.http_encoding = self.http_media_type =\ + self.meta_encoding = self.meta_media_type =\ + self.xml_encoding =\ + None + + def __str__(self): + """ + ``str(EncodingInfo())`` outputs the guessed encoding itself or the empty string + """ + if self.encoding: + return self.encoding + else: + return u'' + + def __repr__(self): + return "<%s.%s object encoding=%r mismatch=%s at 0x%x>" % ( + self.__class__.__module__, self.__class__.__name__, + self.encoding, self.mismatch, id(self)) + + +def buildlog(logname='encutils', level='INFO', stream=sys.stderr, + filename=None, filemode="w", + format='%(levelname)s\t%(message)s'): + """ + helper to build a basic log + + - if ``filename`` is given returns a log logging to ``filename`` with + mode ``filemode`` + - else uses a log streaming to ``stream`` which defaults to + ``sys.stderr`` + - ``level`` defines the level of the log + - ``format`` defines the formatter format of the log + + returns a log with the name ``logname`` + """ + import logging + + log = logging.getLogger(logname) + + if filename: + hdlr = logging.FileHandler(filename, filemode) + else: + hdlr = logging.StreamHandler(stream) + + formatter = logging.Formatter(format) + hdlr.setFormatter(formatter) + + log.addHandler(hdlr) + log.setLevel(logging.__dict__.get(level, logging.INFO)) + + return log + +def _getTextTypeByMediaType(media_type, log=None): + """ + returns type as defined by constants above + """ + if not media_type: + return _OTHER_TYPE + + xml_application_types = [ + ur'application/.*?\+xml', + u'application/xml', + u'application/xml-dtd', + u'application/xml-external-parsed-entity'] + xml_text_types = [ + ur'text\/.*?\+xml', + u'text/xml', + u'text/xml-external-parsed-entity'] + + media_type = media_type.strip().lower() + + if media_type in xml_application_types or\ + re.match(xml_application_types[0], media_type, re.I|re.S|re.X): + return _XML_APPLICATION_TYPE + elif media_type in xml_text_types or\ + re.match(xml_text_types[0], media_type, re.I|re.S|re.X): + return _XML_TEXT_TYPE + elif media_type == u'text/html': + return _HTML_TEXT_TYPE + elif media_type == u'text/css': + return _TEXT_UTF8 + elif media_type.startswith(u'text/'): + return _TEXT_TYPE + else: + return _OTHER_TYPE + +def _getTextType(text, log=None): + """ + checks if given text is XML (**naive test!**) + used if no content-type given + """ + if text[:30].find(u'<?xml version=') != -1: + return _XML_APPLICATION_TYPE + else: + return _OTHER_TYPE + +def encodingByMediaType(media_type, log=None): + """ + Returns a default encoding for the given media_type. + For example ``'utf-8'`` for ``media_type='application/xml'``. + + Refers to RFC 3023 and HTTP MIME specification. + + If no default encoding is available returns ``None``. + """ + defaultencodings = { + _XML_APPLICATION_TYPE: u'utf-8', + _XML_TEXT_TYPE: u'ascii', + _HTML_TEXT_TYPE: u'iso-8859-1', # should be None? + _TEXT_TYPE: u'iso-8859-1', # should be None? + _TEXT_UTF8: u'utf-8', + _OTHER_TYPE: None} + + texttype = _getTextTypeByMediaType(media_type) + encoding = defaultencodings.get(texttype, None) + + if log: + if not encoding: + log.debug(u'"%s" Media-Type has no default encoding', + media_type) + else: + log.debug( + u'Default encoding for Media Type "%s": %s', + media_type, encoding) + return encoding + +def getHTTPInfo(response, log=None): + """ + Returns ``(media_type, encoding)`` information from the response' + Content-Type HTTP header. (Case of headers is ignored.) + May be ``(None, None)`` e.g. if no Content-Type header is + available. + """ + info = response.info() + media_type = info.gettype() + encoding = info.getparam('charset') + + if encoding: + encoding = encoding.lower() + + if log: + log.info(u'HTTP media_type: %s', media_type) + log.info(u'HTTP encoding: %s', encoding) + + return media_type, encoding + +def getMetaInfo(text, log=None): + """ + Returns (media_type, encoding) information from (first) + X/HTML Content-Type ``<meta>`` element if available. + + Normally in X/HTML: + ``<meta http-equiv="Content-Type" content="media_type; + charset=encoding"/>`` + """ + p = _MetaHTMLParser() + p.feed(text) + if p.content_type: + media_type, params = cgi.parse_header(p.content_type) + encoding = params.get('charset') # defaults to None + if encoding: + encoding = encoding.lower() + if log: + log.info(u'HTML META media_type: %s', media_type) + log.info(u'HTML META encoding: %s', encoding) + else: + media_type = encoding = None + + return media_type, encoding + +def detectXMLEncoding(fp, log=None, includeDefault=True): + """ + Attempts to detect the character encoding of the xml file + given by a file object fp. fp must not be a codec wrapped file + object! fp may also be a string or unicode string + + The return value can be: + - if detection of the BOM succeeds, the codec name of the + corresponding unicode charset is returned + + - if BOM detection fails, the xml declaration is searched for + the encoding attribute and its value returned. the "<" + character has to be the very first in the file then (it's xml + standard after all). + + - if BOM and xml declaration fail, utf-8 is returned according + to XML 1.0. + + Based on a recipe by Lars Tiede: + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363841 + which itself is based on Paul Prescotts recipe: + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52257 + """ + if type(fp) in types.StringTypes: + fp = StringIO.StringIO(fp) + + ### detection using BOM + + ## the BOMs we know, by their pattern + bomDict={ # bytepattern: name + (0x00, 0x00, 0xFE, 0xFF) : "utf_32_be", + (0xFF, 0xFE, 0x00, 0x00) : "utf_32_le", + (0xFE, 0xFF, None, None) : "utf_16_be", + (0xFF, 0xFE, None, None) : "utf_16_le", + (0xEF, 0xBB, 0xBF, None) : "utf-8", + } + + ## go to beginning of file and get the first 4 bytes + oldFP = fp.tell() + fp.seek(0) + (byte1, byte2, byte3, byte4) = tuple(map(ord, fp.read(4))) + + ## try bom detection using 4 bytes, 3 bytes, or 2 bytes + bomDetection = bomDict.get((byte1, byte2, byte3, byte4)) + if not bomDetection: + bomDetection = bomDict.get((byte1, byte2, byte3, None)) + if not bomDetection: + bomDetection = bomDict.get((byte1, byte2, None, None)) + + ## if BOM detected, we're done :-) + if bomDetection: + if log: + log.info(u'XML BOM encoding: %s' % bomDetection) + fp.seek(oldFP) + return bomDetection + + ## still here? BOM detection failed. + ## now that BOM detection has failed we assume one byte character + ## encoding behaving ASCII + + ### search xml declaration for encoding attribute + + ## assume xml declaration fits into the first 2 KB (*cough*) + fp.seek(0) + buffer = fp.read(2048) + + ## set up regular expression + xmlDeclPattern = r""" + ^<\?xml # w/o BOM, xmldecl starts with <?xml at the first byte + .+? # some chars (version info), matched minimal + encoding= # encoding attribute begins + ["'] # attribute start delimiter + (?P<encstr> # what's matched in the brackets will be named encstr + [^"']+ # every character not delimiter (not overly exact!) + ) # closes the brackets pair for the named group + ["'] # attribute end delimiter + .*? # some chars optionally (standalone decl or whitespace) + \?> # xmldecl end + """ + xmlDeclRE = re.compile(xmlDeclPattern, re.VERBOSE) + + ## search and extract encoding string + match = xmlDeclRE.search(buffer) + fp.seek(oldFP) + if match: + enc = match.group("encstr").lower() + if log: + log.info(u'XML encoding="%s"' % enc) + return enc + else: + if includeDefault: + if log: + log.info(u'XML encoding default utf-8') + return u'utf-8' + else: + return None + +def tryEncodings(text, log=None): + """ + If installed uses chardet http://chardet.feedparser.org/ to detect + encoding, else tries different encodings on text and returns the one + that does not raise an exception which is not very advanced or may + be totally wrong. + + Returns working encoding or None if no encoding does work at all. + + The returned encoding might nevertheless be not the one intended by the + author as it is only checked if the text might be encoded in that + encoding. Some texts might be working in "iso-8859-1" *and* + "windows-1252" *and* "ascii" *and* "utf-8" and ... + """ + try: + import chardet + encoding = chardet.detect(text)["encoding"] + + except ImportError: + msg = 'Using simplified encoding detection, you might want to install chardet.' + if log: + log.warn(msg) + else: + print msg + + encodings = ( + 'ascii', + 'iso-8859-1', + 'windows-1252', + 'utf-8' + ) + encoding = None + for e in encodings: + try: + text.encode(e) + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + encoding = e + break + + return encoding + +def getEncodingInfo(response=None, text=u'', log=None, url=None): + """ + Finds all encoding related information in given ``text``. + Uses information in headers of supplied HTTPResponse, possible XML + declaration and X/HTML ``<meta>`` elements. + ``text`` will mostly be HTML or XML. + + Parameters + - ``response``: HTTP response object, + e.g. ``urllib.urlopen('url')`` + - ``text``: to guess encoding for, might include XML + prolog with encoding pseudo attribute or HTML meta element + - ``log``: an optional logging logger to which messages may go, if + no log given all log messages are available from resulting + ``EncodingInfo`` + + May also simply be called with ``getEncodingInfo(url='URL')`` which fetches + the url and all needed information. + + Returns instance of ``EncodingInfo``. + + How the resulting encoding is retrieved + ======================================= + XML + --- + RFC 3023 states if media type given in the Content-Type HTTP header is + application/xml, application/xml-dtd, + application/xml-external-parsed-entity, or any one of the subtypes of + application/xml such as application/atom+xml or application/rss+xml + etc then the character encoding is determined in this order: + + 1. the encoding given in the charset parameter of the Content-Type HTTP + header, or + 2. the encoding given in the encoding attribute of the XML declaration + within the document, or + 3. utf-8. + + Mismatch possibilities: + - HTTP + XMLdecla + - HTTP + HTMLmeta + + application/xhtml+xml ? + XMLdecla + HTMLmeta + + If the media type given in the Content-Type HTTP header is text/xml, + text/xml-external-parsed-entity, or a subtype like text/Anything+xml, + the encoding attribute of the XML declaration is ignored completely + and the character encoding is determined in the order: + 1. the encoding given in the charset parameter of the Content-Type HTTP + header, or + 2. ascii. + + Mismatch possibilities: + - HTTP + XMLdecla + - HTTP + HTMLmeta + + text/xhtml+xml + XMLdecla + HTMLmeta + + HTML + ---- + For HTML served as text/html: + http://www.w3.org/TR/REC-html40/charset.html#h-5.2.2 + + 1. An HTTP "charset" parameter in a "Content-Type" field. + (maybe defaults to ISO-8859-1, but should not assume this) + 2. A META declaration with "http-equiv" set to "Content-Type" and a + value set for "charset". + 3. The charset attribute set on an element that designates an external + resource. (NOT IMPLEMENTED HERE YET) + + Mismatch possibilities: + - HTTP + HTMLmeta + + TEXT + ---- + For most text/* types the encoding will be reported as iso-8859-1. + Exceptions are XML formats send as text/* mime type (see above) and + text/css which has a default encoding of UTF-8. + """ + if url: + try: + response = urllib.urlopen(url) + text = response.read() + except IOError, e: + print IOError(e) + sys.exit(1) + + encinfo = EncodingInfo() + + logstream = StringIO.StringIO() + if not log: + log = buildlog(stream=logstream, format='%(message)s') + + # HTTP + if response: + encinfo.http_media_type, encinfo.http_encoding = getHTTPInfo( + response, log) + texttype = _getTextTypeByMediaType(encinfo.http_media_type, log) + else: + # check if maybe XML or (TODO:) HTML + texttype = _getTextType(text, log) + + # XML (also XHTML served as text/html) + if texttype == _XML_APPLICATION_TYPE or texttype == _XML_TEXT_TYPE: + encinfo.xml_encoding = detectXMLEncoding(text, log) + + # XML (also XHTML served as text/html) + if texttype == _HTML_TEXT_TYPE: + encinfo.xml_encoding = detectXMLEncoding(text, log, includeDefault=False) + + # HTML + if texttype == _HTML_TEXT_TYPE or texttype == _TEXT_TYPE: + encinfo.meta_media_type, encinfo.meta_encoding = getMetaInfo( + text, log) + + # guess + # 1. HTTP charset? + encinfo.encoding = encinfo.http_encoding + encinfo.mismatch = False + + # 2. media_type? + # XML application/... + if texttype == _XML_APPLICATION_TYPE: + if not encinfo.encoding: + encinfo.encoding = encinfo.xml_encoding + # xml_encoding has default of utf-8 + + # text/html + elif texttype == _HTML_TEXT_TYPE: + if not encinfo.encoding: + encinfo.encoding = encinfo.meta_encoding + if not encinfo.encoding: + encinfo.encoding = encodingByMediaType(encinfo.http_media_type) + if not encinfo.encoding: + encinfo.encoding = tryEncodings(text) + + # text/... + xml or text/* + elif texttype == _XML_TEXT_TYPE or texttype == _TEXT_TYPE: + if not encinfo.encoding: + encinfo.encoding = encodingByMediaType(encinfo.http_media_type) + + # possible mismatches, checks if present at all and then if equal + # HTTP + XML + if encinfo.http_encoding and encinfo.xml_encoding and\ + encinfo.http_encoding <> encinfo.xml_encoding: + encinfo.mismatch = True + log.warn(u'"%s" (HTTP) <> "%s" (XML) encoding mismatch' % + (encinfo.http_encoding, encinfo.xml_encoding)) + # HTTP + Meta + if encinfo.http_encoding and encinfo.meta_encoding and\ + encinfo.http_encoding <> encinfo.meta_encoding: + encinfo.mismatch = True + log.warn(u'"%s" (HTTP) <> "%s" (HTML <meta>) encoding mismatch' % + (encinfo.http_encoding, encinfo.meta_encoding)) + # XML + Meta + if encinfo.xml_encoding and encinfo.meta_encoding and\ + encinfo.xml_encoding <> encinfo.meta_encoding: + encinfo.mismatch = True + log.warn(u'"%s" (XML) <> "%s" (HTML <meta>) encoding mismatch' % + (encinfo.xml_encoding, encinfo.meta_encoding)) + + log.info(u'Encoding (probably): %s (Mismatch: %s)', + encinfo.encoding, encinfo.mismatch) + + encinfo.logtext = logstream.getvalue() + return encinfo + + +if __name__ == '__main__': + import pydoc + pydoc.help(__name__) \ No newline at end of file diff --git a/src/odf/__init__.py b/src/odf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/odf/anim.py b/src/odf/anim.py new file mode 100644 index 0000000000..27dca36ca8 --- /dev/null +++ b/src/odf/anim.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import ANIMNS +from element import Element + + +# Autogenerated +def Animate(**args): + return Element(qname = (ANIMNS,'animate'), **args) + +def Animatecolor(**args): + return Element(qname = (ANIMNS,'animateColor'), **args) + +def Animatemotion(**args): + return Element(qname = (ANIMNS,'animateMotion'), **args) + +def Animatetransform(**args): + return Element(qname = (ANIMNS,'animateTransform'), **args) + +def Audio(**args): + return Element(qname = (ANIMNS,'audio'), **args) + +def Command(**args): + return Element(qname = (ANIMNS,'command'), **args) + +def Iterate(**args): + return Element(qname = (ANIMNS,'iterate'), **args) + +def Par(**args): + return Element(qname = (ANIMNS,'par'), **args) + +def Param(**args): + return Element(qname = (ANIMNS,'param'), **args) + +def Seq(**args): + return Element(qname = (ANIMNS,'seq'), **args) + +def Set(**args): + return Element(qname = (ANIMNS,'set'), **args) + +def Transitionfilter(**args): + return Element(qname = (ANIMNS,'transitionFilter'), **args) + diff --git a/src/odf/attrconverters.py b/src/odf/attrconverters.py new file mode 100644 index 0000000000..9abdf0502b --- /dev/null +++ b/src/odf/attrconverters.py @@ -0,0 +1,1444 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +from namespaces import * +import re, types + +pattern_color = re.compile(r'#[0-9a-fA-F]{6}') +pattern_vector3D = re.compile(r'\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)){2}[ ]*\)') + +def make_NCName(arg): + for c in (':',' '): + arg = arg.replace(c,"_%x_" % ord(c)) + return arg + +def cnv_anyURI(attribute, arg, element): + return unicode(arg) + +def cnv_boolean(attribute, arg, element): + if arg.lower() in ("false","no"): + return "false" + if arg: + return "true" + return "false" + +# Potentially accept color values +def cnv_color(attribute, arg, element): + return str(arg) + +def cnv_configtype(attribute, arg, element): + if str(arg) not in ("boolean", "short", "int", "long", + "double", "string", "datetime", "base64Binary"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def cnv_data_source_has_labels(attribute, arg, element): + if str(arg) not in ("none","row","column","both"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +# Understand different date formats +def cnv_date(attribute, arg, element): + return str(arg) + +def cnv_dateTime(attribute, arg, element): + return str(arg) + +def cnv_double(attribute, arg, element): + return str(arg) + +def cnv_duration(attribute, arg, element): + return str(arg) + +def cnv_family(attribute, arg, element): + if str(arg) not in ("text", "paragraph", "section", "ruby", "table", "table-column", "table-row", "table-cell", + "graphic", "presentation", "drawing-page", "chart"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def cnv_ID(attribute, arg, element): + return str(arg) + +def cnv_IDREF(attribute, arg, element): + return str(arg) + +def cnv_integer(attribute, arg, element): + return str(arg) + +def cnv_legend_position(attribute, arg, element): + if str(arg) not in ("start", "end", "top", "bottom", "top-start", "bottom-start", "top-end", "bottom-end"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +pattern_length = re.compile(r'-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))') + +def cnv_length(attribute, arg, element): + global pattern_length + if not pattern_length.match(arg): + raise ValueError, "'%s' is not a valid length" % arg + return arg + +def cnv_lengthorpercent(attribute, arg, element): + failed = False + try: return cnv_length(attribute, arg, element) + except: failed = True + try: return cnv_percent(attribute, arg, element) + except: failed = True + if failed: + raise ValueError, "'%s' is not a valid length or percent" % arg + return arg + +def cnv_metavaluetype(attribute, arg, element): + if str(arg) not in ("float", "date", "time", "boolean", "string"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def cnv_major_minor(attribute, arg, element): + if arg not in ('major','minor'): + raise ValueError, "'%s' is not either 'minor' or 'major'" % arg + +pattern_namespacedToken = re.compile(r'[0-9a-zA-Z_]+:[0-9a-zA-Z._\-]+') + +def cnv_namespacedToken(attribute, arg, element): + global pattern_namespacedToken + + if not pattern_namespacedToken.match(arg): + raise ValueError, "'%s' is not a valid namespaced token" % arg + return arg + +# Must accept string as argument +# NCName is defined in http://www.w3.org/TR/REC-xml-names/#NT-NCName +# Essentially an XML name minus ':' +def cnv_NCName(attribute, arg, element): + if type(arg) in types.StringTypes: + return make_NCName(arg) + else: + return arg.getAttrNS(STYLENS, 'name') + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_StyleNameRef(attribute, arg, element): + try: + return arg.getAttrNS(STYLENS, 'name') + except: + return arg + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_DrawNameRef(attribute, arg, element): + try: + return arg.getAttrNS(DRAWNS, 'name') + except: + return arg + +# Must accept list of Style objects +def cnv_NCNames(attribute, arg, element): + return ' '.join(arg) + +def cnv_nonNegativeInteger(attribute, arg, element): + return str(arg) + +pattern_percent = re.compile(r'-?([0-9]+(\.[0-9]*)?|\.[0-9]+)%') + +def cnv_percent(attribute, arg, element): + global pattern_percent + if not pattern_percent.match(arg): + raise ValueError, "'%s' is not a valid length" % arg + return arg + +# Real one doesn't allow floating point values +pattern_points = re.compile(r'-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*') +#pattern_points = re.compile(r'-?[0-9.]+,-?[0-9.]+([ ]+-?[0-9.]+,-?[0-9.]+)*') +def cnv_points(attribute, arg, element): + global pattern_points + if type(arg) in types.StringTypes: + if not pattern_points.match(arg): + raise ValueError, "x,y are separated by a comma and the points are separated by white spaces" + return arg + else: + try: + strarg = ' '.join([ "%d,%d" % p for p in arg]) + except: + raise ValueError, "Points must be string or [(0,0),(1,1)] - not %s" % arg + return strarg + +def cnv_position(attribute, arg, element): + if element == (STYLENS,u'tab-stop'): + return cnv_length(attribute, arg, element) + return cnv_string(attribute, arg, element) + +def cnv_positiveInteger(attribute, arg, element): + return str(arg) + +def cnv_string(attribute, arg, element): + return unicode(arg) + +def cnv_textnoteclass(attribute, arg, element): + if str(arg) not in ("footnote", "endnote"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +# Understand different time formats +def cnv_time(attribute, arg, element): + return str(arg) + +def cnv_token(attribute, arg, element): + return str(arg) + +pattern_viewbox = re.compile(r'-?[0-9]+([ ]+-?[0-9]+){3}$') + +def cnv_viewbox(attribute, arg, element): + global pattern_viewbox + if not pattern_viewbox.match(arg): + raise ValueError, "viewBox must be four integers separated by whitespaces" + return arg + +def cnv_xlinkshow(attribute, arg, element): + if str(arg) not in ("new", "replace", "embed"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + + +attrconverters = { + ((ANIMNS,u'audio-level'), None): cnv_double, + ((ANIMNS,u'color-interpolation'), None): cnv_string, + ((ANIMNS,u'color-interpolation-direction'), None): cnv_string, + ((ANIMNS,u'command'), None): cnv_string, + ((ANIMNS,u'formula'), None): cnv_string, + ((ANIMNS,u'id'), None): cnv_ID, + ((ANIMNS,u'iterate-interval'), None): cnv_duration, + ((ANIMNS,u'iterate-type'), None): cnv_string, + ((ANIMNS,u'name'), None): cnv_string, + ((ANIMNS,u'sub-item'), None): cnv_string, + ((ANIMNS,u'value'), None): cnv_string, + ((CHARTNS,u'attached-axis'), None): cnv_string, + ((CHARTNS,u'class'), (CHARTNS,u'grid')): cnv_major_minor, + ((CHARTNS,u'class'), None): cnv_namespacedToken, + ((CHARTNS,u'column-mapping'), None): cnv_string, + ((CHARTNS,u'connect-bars'), None): cnv_boolean, + ((CHARTNS,u'data-label-number'), None): cnv_string, + ((CHARTNS,u'data-label-symbol'), None): cnv_boolean, + ((CHARTNS,u'data-label-text'), None): cnv_boolean, + ((CHARTNS,u'data-source-has-labels'), None): cnv_data_source_has_labels, + ((CHARTNS,u'deep'), None): cnv_boolean, + ((CHARTNS,u'dimension'), None): cnv_string, + ((CHARTNS,u'display-label'), None): cnv_boolean, + ((CHARTNS,u'error-category'), None): cnv_string, + ((CHARTNS,u'error-lower-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-lower-limit'), None): cnv_string, + ((CHARTNS,u'error-margin'), None): cnv_string, + ((CHARTNS,u'error-percentage'), None): cnv_string, + ((CHARTNS,u'error-upper-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-upper-limit'), None): cnv_string, + ((CHARTNS,u'gap-width'), None): cnv_string, + ((CHARTNS,u'interpolation'), None): cnv_string, + ((CHARTNS,u'interval-major'), None): cnv_string, + ((CHARTNS,u'interval-minor'), None): cnv_string, + ((CHARTNS,u'japanese-candle-stick'), None): cnv_boolean, + ((CHARTNS,u'label-arrangement'), None): cnv_string, + ((CHARTNS,u'label-cell-address'), None): cnv_string, + ((CHARTNS,u'legend-align'), None): cnv_string, + ((CHARTNS,u'legend-position'), None): cnv_legend_position, + ((CHARTNS,u'lines'), None): cnv_boolean, + ((CHARTNS,u'link-data-style-to-source'), None): cnv_boolean, + ((CHARTNS,u'logarithmic'), None): cnv_boolean, + ((CHARTNS,u'maximum'), None): cnv_string, + ((CHARTNS,u'mean-value'), None): cnv_boolean, + ((CHARTNS,u'minimum'), None): cnv_string, + ((CHARTNS,u'name'), None): cnv_string, + ((CHARTNS,u'origin'), None): cnv_string, + ((CHARTNS,u'overlap'), None): cnv_string, + ((CHARTNS,u'percentage'), None): cnv_boolean, + ((CHARTNS,u'pie-offset'), None): cnv_string, + ((CHARTNS,u'regression-type'), None): cnv_string, + ((CHARTNS,u'repeated'), None): cnv_nonNegativeInteger, + ((CHARTNS,u'row-mapping'), None): cnv_string, + ((CHARTNS,u'scale-text'), None): cnv_boolean, + ((CHARTNS,u'series-source'), None): cnv_string, + ((CHARTNS,u'solid-type'), None): cnv_string, + ((CHARTNS,u'spline-order'), None): cnv_string, + ((CHARTNS,u'spline-resolution'), None): cnv_string, + ((CHARTNS,u'stacked'), None): cnv_boolean, + ((CHARTNS,u'style-name'), None): cnv_StyleNameRef, + ((CHARTNS,u'symbol-height'), None): cnv_string, + ((CHARTNS,u'symbol-name'), None): cnv_string, + ((CHARTNS,u'symbol-type'), None): cnv_string, + ((CHARTNS,u'symbol-width'), None): cnv_string, + ((CHARTNS,u'text-overlap'), None): cnv_boolean, + ((CHARTNS,u'three-dimensional'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-major-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-major-outer'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-outer'), None): cnv_boolean, + ((CHARTNS,u'values-cell-range-address'), None): cnv_string, + ((CHARTNS,u'vertical'), None): cnv_boolean, + ((CHARTNS,u'visible'), None): cnv_boolean, + ((CONFIGNS,u'name'), None): cnv_string, + ((CONFIGNS,u'type'), None): cnv_configtype, + ((DR3DNS,u'ambient-color'), None): cnv_string, + ((DR3DNS,u'back-scale'), None): cnv_string, + ((DR3DNS,u'backface-culling'), None): cnv_string, + ((DR3DNS,u'center'), None): cnv_string, + ((DR3DNS,u'close-back'), None): cnv_boolean, + ((DR3DNS,u'close-front'), None): cnv_boolean, + ((DR3DNS,u'depth'), None): cnv_length, + ((DR3DNS,u'diffuse-color'), None): cnv_string, + ((DR3DNS,u'direction'), None): cnv_string, + ((DR3DNS,u'distance'), None): cnv_length, + ((DR3DNS,u'edge-rounding'), None): cnv_string, + ((DR3DNS,u'edge-rounding-mode'), None): cnv_string, + ((DR3DNS,u'emissive-color'), None): cnv_string, + ((DR3DNS,u'enabled'), None): cnv_boolean, + ((DR3DNS,u'end-angle'), None): cnv_string, + ((DR3DNS,u'focal-length'), None): cnv_length, + ((DR3DNS,u'horizontal-segments'), None): cnv_string, + ((DR3DNS,u'lighting-mode'), None): cnv_boolean, + ((DR3DNS,u'max-edge'), None): cnv_string, + ((DR3DNS,u'min-edge'), None): cnv_string, + ((DR3DNS,u'normals-direction'), None): cnv_string, + ((DR3DNS,u'normals-kind'), None): cnv_string, + ((DR3DNS,u'projection'), None): cnv_string, + ((DR3DNS,u'shade-mode'), None): cnv_string, + ((DR3DNS,u'shadow'), None): cnv_string, + ((DR3DNS,u'shadow-slant'), None): cnv_nonNegativeInteger, + ((DR3DNS,u'shininess'), None): cnv_string, + ((DR3DNS,u'size'), None): cnv_string, + ((DR3DNS,u'specular'), None): cnv_boolean, + ((DR3DNS,u'specular-color'), None): cnv_string, + ((DR3DNS,u'texture-filter'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-x'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-y'), None): cnv_string, + ((DR3DNS,u'texture-kind'), None): cnv_string, + ((DR3DNS,u'texture-mode'), None): cnv_string, + ((DR3DNS,u'transform'), None): cnv_string, + ((DR3DNS,u'vertical-segments'), None): cnv_string, + ((DR3DNS,u'vpn'), None): cnv_string, + ((DR3DNS,u'vrp'), None): cnv_string, + ((DR3DNS,u'vup'), None): cnv_string, + ((DRAWNS,u'align'), None): cnv_string, + ((DRAWNS,u'angle'), None): cnv_integer, + ((DRAWNS,u'archive'), None): cnv_string, + ((DRAWNS,u'auto-grow-height'), None): cnv_boolean, + ((DRAWNS,u'auto-grow-width'), None): cnv_boolean, + ((DRAWNS,u'background-size'), None): cnv_string, + ((DRAWNS,u'blue'), None): cnv_string, + ((DRAWNS,u'border'), None): cnv_string, + ((DRAWNS,u'caption-angle'), None): cnv_string, + ((DRAWNS,u'caption-angle-type'), None): cnv_string, + ((DRAWNS,u'caption-escape'), None): cnv_string, + ((DRAWNS,u'caption-escape-direction'), None): cnv_string, + ((DRAWNS,u'caption-fit-line-length'), None): cnv_boolean, + ((DRAWNS,u'caption-gap'), None): cnv_string, + ((DRAWNS,u'caption-line-length'), None): cnv_length, + ((DRAWNS,u'caption-point-x'), None): cnv_string, + ((DRAWNS,u'caption-point-y'), None): cnv_string, + ((DRAWNS,u'caption-type'), None): cnv_string, + ((DRAWNS,u'chain-next-name'), None): cnv_string, + ((DRAWNS,u'class-id'), None): cnv_string, + ((DRAWNS,u'class-names'), None): cnv_NCNames, + ((DRAWNS,u'code'), None): cnv_string, + ((DRAWNS,u'color'), None): cnv_string, + ((DRAWNS,u'color-inversion'), None): cnv_boolean, + ((DRAWNS,u'color-mode'), None): cnv_string, + ((DRAWNS,u'concave'), None): cnv_string, + ((DRAWNS,u'concentric-gradient-fill-allowed'), None): cnv_boolean, + ((DRAWNS,u'contrast'), None): cnv_string, + ((DRAWNS,u'control'), None): cnv_IDREF, + ((DRAWNS,u'copy-of'), None): cnv_string, + ((DRAWNS,u'corner-radius'), None): cnv_length, + ((DRAWNS,u'corners'), None): cnv_positiveInteger, + ((DRAWNS,u'cx'), None): cnv_string, + ((DRAWNS,u'cy'), None): cnv_string, + ((DRAWNS,u'data'), None): cnv_string, + ((DRAWNS,u'decimal-places'), None): cnv_string, + ((DRAWNS,u'display'), None): cnv_string, + ((DRAWNS,u'display-name'), None): cnv_string, + ((DRAWNS,u'distance'), None): cnv_string, + ((DRAWNS,u'dots1'), None): cnv_integer, + ((DRAWNS,u'dots1-length'), None): cnv_length, + ((DRAWNS,u'dots2'), None): cnv_integer, + ((DRAWNS,u'dots2-length'), None): cnv_length, + ((DRAWNS,u'end-angle'), None): cnv_double, + ((DRAWNS,u'end'), None): cnv_string, + ((DRAWNS,u'end-color'), None): cnv_string, + ((DRAWNS,u'end-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'end-guide'), None): cnv_length, + ((DRAWNS,u'end-intensity'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'end-shape'), None): cnv_IDREF, + ((DRAWNS,u'engine'), None): cnv_string, + ((DRAWNS,u'enhanced-path'), None): cnv_string, + ((DRAWNS,u'escape-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-allowed'), None): cnv_boolean, + ((DRAWNS,u'extrusion-brightness'), None): cnv_string, + ((DRAWNS,u'extrusion'), None): cnv_boolean, + ((DRAWNS,u'extrusion-color'), None): cnv_boolean, + ((DRAWNS,u'extrusion-depth'), None): cnv_double, + ((DRAWNS,u'extrusion-diffusion'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-first-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-light-face'), None): cnv_boolean, + ((DRAWNS,u'extrusion-metal'), None): cnv_boolean, + ((DRAWNS,u'extrusion-number-of-line-segments'), None): cnv_integer, + ((DRAWNS,u'extrusion-origin'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-angle'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-center'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-second-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-shininess'), None): cnv_string, + ((DRAWNS,u'extrusion-skew'), None): cnv_double, + ((DRAWNS,u'extrusion-specularity'), None): cnv_string, + ((DRAWNS,u'extrusion-viewpoint'), None): cnv_string, + ((DRAWNS,u'fill'), None): cnv_string, + ((DRAWNS,u'fill-color'), None): cnv_string, + ((DRAWNS,u'fill-gradient-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-solid'), None): cnv_boolean, + ((DRAWNS,u'fill-image-height'), None): cnv_lengthorpercent, + ((DRAWNS,u'fill-image-name'), None): cnv_DrawNameRef, + ((DRAWNS,u'fill-image-ref-point'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-x'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-y'), None): cnv_string, + ((DRAWNS,u'fill-image-width'), None): cnv_lengthorpercent, + ((DRAWNS,u'filter-name'), None): cnv_string, + ((DRAWNS,u'fit-to-contour'), None): cnv_boolean, + ((DRAWNS,u'fit-to-size'), None): cnv_boolean, + ((DRAWNS,u'formula'), None): cnv_string, + ((DRAWNS,u'frame-display-border'), None): cnv_boolean, + ((DRAWNS,u'frame-display-scrollbar'), None): cnv_boolean, + ((DRAWNS,u'frame-margin-horizontal'), None): cnv_string, + ((DRAWNS,u'frame-margin-vertical'), None): cnv_string, + ((DRAWNS,u'frame-name'), None): cnv_string, + ((DRAWNS,u'gamma'), None): cnv_string, + ((DRAWNS,u'glue-point-leaving-directions'), None): cnv_string, + ((DRAWNS,u'glue-point-type'), None): cnv_string, + ((DRAWNS,u'glue-points'), None): cnv_string, + ((DRAWNS,u'gradient-step-count'), None): cnv_string, + ((DRAWNS,u'green'), None): cnv_string, + ((DRAWNS,u'guide-distance'), None): cnv_string, + ((DRAWNS,u'guide-overhang'), None): cnv_length, + ((DRAWNS,u'handle-mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'handle-mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'handle-polar'), None): cnv_string, + ((DRAWNS,u'handle-position'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-maximum'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-minimum'), None): cnv_string, + ((DRAWNS,u'handle-switched'), None): cnv_boolean, +# ((DRAWNS,u'id'), None): cnv_ID, +# ((DRAWNS,u'id'), None): cnv_nonNegativeInteger, # ?? line 6581 in RNG + ((DRAWNS,u'id'), None): cnv_string, + ((DRAWNS,u'image-opacity'), None): cnv_string, + ((DRAWNS,u'kind'), None): cnv_string, + ((DRAWNS,u'layer'), None): cnv_string, + ((DRAWNS,u'line-distance'), None): cnv_string, + ((DRAWNS,u'line-skew'), None): cnv_string, + ((DRAWNS,u'luminance'), None): cnv_string, + ((DRAWNS,u'marker-end-center'), None): cnv_boolean, + ((DRAWNS,u'marker-end'), None): cnv_string, + ((DRAWNS,u'marker-end-width'), None): cnv_length, + ((DRAWNS,u'marker-start-center'), None): cnv_boolean, + ((DRAWNS,u'marker-start'), None): cnv_string, + ((DRAWNS,u'marker-start-width'), None): cnv_length, + ((DRAWNS,u'master-page-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'may-script'), None): cnv_boolean, + ((DRAWNS,u'measure-align'), None): cnv_string, + ((DRAWNS,u'measure-vertical-align'), None): cnv_string, + ((DRAWNS,u'mime-type'), None): cnv_string, + ((DRAWNS,u'mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'modifiers'), None): cnv_string, + ((DRAWNS,u'name'), None): cnv_NCName, +# ((DRAWNS,u'name'), None): cnv_string, + ((DRAWNS,u'nohref'), None): cnv_string, + ((DRAWNS,u'notify-on-update-of-ranges'), None): cnv_string, + ((DRAWNS,u'object'), None): cnv_string, + ((DRAWNS,u'ole-draw-aspect'), None): cnv_string, + ((DRAWNS,u'opacity'), None): cnv_string, + ((DRAWNS,u'opacity-name'), None): cnv_string, + ((DRAWNS,u'page-number'), None): cnv_positiveInteger, + ((DRAWNS,u'parallel'), None): cnv_boolean, + ((DRAWNS,u'path-stretchpoint-x'), None): cnv_double, + ((DRAWNS,u'path-stretchpoint-y'), None): cnv_double, + ((DRAWNS,u'placing'), None): cnv_string, + ((DRAWNS,u'points'), None): cnv_points, + ((DRAWNS,u'protected'), None): cnv_boolean, + ((DRAWNS,u'recreate-on-edit'), None): cnv_boolean, + ((DRAWNS,u'red'), None): cnv_string, + ((DRAWNS,u'rotation'), None): cnv_integer, + ((DRAWNS,u'secondary-fill-color'), None): cnv_string, + ((DRAWNS,u'shadow'), None): cnv_string, + ((DRAWNS,u'shadow-color'), None): cnv_string, + ((DRAWNS,u'shadow-offset-x'), None): cnv_length, + ((DRAWNS,u'shadow-offset-y'), None): cnv_length, + ((DRAWNS,u'shadow-opacity'), None): cnv_string, + ((DRAWNS,u'shape-id'), None): cnv_IDREF, + ((DRAWNS,u'sharpness'), None): cnv_string, + ((DRAWNS,u'show-unit'), None): cnv_boolean, + ((DRAWNS,u'start-angle'), None): cnv_double, + ((DRAWNS,u'start'), None): cnv_string, + ((DRAWNS,u'start-color'), None): cnv_string, + ((DRAWNS,u'start-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'start-guide'), None): cnv_length, + ((DRAWNS,u'start-intensity'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'start-shape'), None): cnv_IDREF, + ((DRAWNS,u'stroke'), None): cnv_string, + ((DRAWNS,u'stroke-dash'), None): cnv_string, + ((DRAWNS,u'stroke-dash-names'), None): cnv_string, + ((DRAWNS,u'stroke-linejoin'), None): cnv_string, + ((DRAWNS,u'style'), None): cnv_string, + ((DRAWNS,u'style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'symbol-color'), None): cnv_string, + ((DRAWNS,u'text-areas'), None): cnv_string, + ((DRAWNS,u'text-path-allowed'), None): cnv_boolean, + ((DRAWNS,u'text-path'), None): cnv_boolean, + ((DRAWNS,u'text-path-mode'), None): cnv_string, + ((DRAWNS,u'text-path-same-letter-heights'), None): cnv_boolean, + ((DRAWNS,u'text-path-scale'), None): cnv_string, + ((DRAWNS,u'text-rotate-angle'), None): cnv_double, + ((DRAWNS,u'text-style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'textarea-horizontal-align'), None): cnv_string, + ((DRAWNS,u'textarea-vertical-align'), None): cnv_string, + ((DRAWNS,u'tile-repeat-offset'), None): cnv_string, + ((DRAWNS,u'transform'), None): cnv_string, + ((DRAWNS,u'type'), None): cnv_string, + ((DRAWNS,u'unit'), None): cnv_string, + ((DRAWNS,u'value'), None): cnv_string, + ((DRAWNS,u'visible-area-height'), None): cnv_string, + ((DRAWNS,u'visible-area-left'), None): cnv_string, + ((DRAWNS,u'visible-area-top'), None): cnv_string, + ((DRAWNS,u'visible-area-width'), None): cnv_string, + ((DRAWNS,u'wrap-influence-on-position'), None): cnv_string, + ((DRAWNS,u'z-index'), None): cnv_nonNegativeInteger, + ((FONS,u'background-color'), None): cnv_string, + ((FONS,u'border-bottom'), None): cnv_string, + ((FONS,u'border'), None): cnv_string, + ((FONS,u'border-left'), None): cnv_string, + ((FONS,u'border-right'), None): cnv_string, + ((FONS,u'border-top'), None): cnv_string, + ((FONS,u'break-after'), None): cnv_string, + ((FONS,u'break-before'), None): cnv_string, + ((FONS,u'clip'), None): cnv_string, + ((FONS,u'color'), None): cnv_string, + ((FONS,u'column-count'), None): cnv_positiveInteger, + ((FONS,u'column-gap'), None): cnv_length, + ((FONS,u'country'), None): cnv_token, + ((FONS,u'end-indent'), None): cnv_length, + ((FONS,u'font-family'), None): cnv_string, + ((FONS,u'font-size'), None): cnv_string, + ((FONS,u'font-style'), None): cnv_string, + ((FONS,u'font-variant'), None): cnv_string, + ((FONS,u'font-weight'), None): cnv_string, + ((FONS,u'height'), None): cnv_string, + ((FONS,u'hyphenate'), None): cnv_boolean, + ((FONS,u'hyphenation-keep'), None): cnv_string, + ((FONS,u'hyphenation-ladder-count'), None): cnv_string, + ((FONS,u'hyphenation-push-char-count'), None): cnv_string, + ((FONS,u'hyphenation-remain-char-count'), None): cnv_string, + ((FONS,u'keep-together'), None): cnv_string, + ((FONS,u'keep-with-next'), None): cnv_string, + ((FONS,u'language'), None): cnv_token, + ((FONS,u'letter-spacing'), None): cnv_string, + ((FONS,u'line-height'), None): cnv_string, + ((FONS,u'margin-bottom'), None): cnv_string, + ((FONS,u'margin'), None): cnv_string, + ((FONS,u'margin-left'), None): cnv_string, + ((FONS,u'margin-right'), None): cnv_string, + ((FONS,u'margin-top'), None): cnv_string, + ((FONS,u'max-height'), None): cnv_string, + ((FONS,u'max-width'), None): cnv_string, + ((FONS,u'min-height'), None): cnv_length, + ((FONS,u'min-width'), None): cnv_string, + ((FONS,u'orphans'), None): cnv_string, + ((FONS,u'padding-bottom'), None): cnv_string, + ((FONS,u'padding'), None): cnv_string, + ((FONS,u'padding-left'), None): cnv_string, + ((FONS,u'padding-right'), None): cnv_string, + ((FONS,u'padding-top'), None): cnv_string, + ((FONS,u'page-height'), None): cnv_length, + ((FONS,u'page-width'), None): cnv_length, + ((FONS,u'space-after'), None): cnv_length, + ((FONS,u'space-before'), None): cnv_length, + ((FONS,u'start-indent'), None): cnv_length, + ((FONS,u'text-align'), None): cnv_string, + ((FONS,u'text-align-last'), None): cnv_string, + ((FONS,u'text-indent'), None): cnv_string, + ((FONS,u'text-shadow'), None): cnv_string, + ((FONS,u'text-transform'), None): cnv_string, + ((FONS,u'widows'), None): cnv_string, + ((FONS,u'width'), None): cnv_string, + ((FONS,u'wrap-option'), None): cnv_string, + ((FORMNS,u'allow-deletes'), None): cnv_boolean, + ((FORMNS,u'allow-inserts'), None): cnv_boolean, + ((FORMNS,u'allow-updates'), None): cnv_boolean, + ((FORMNS,u'apply-design-mode'), None): cnv_boolean, + ((FORMNS,u'apply-filter'), None): cnv_boolean, + ((FORMNS,u'auto-complete'), None): cnv_boolean, + ((FORMNS,u'automatic-focus'), None): cnv_boolean, + ((FORMNS,u'bound-column'), None): cnv_string, + ((FORMNS,u'button-type'), None): cnv_string, + ((FORMNS,u'command'), None): cnv_string, + ((FORMNS,u'command-type'), None): cnv_string, + ((FORMNS,u'control-implementation'), None): cnv_string, + ((FORMNS,u'convert-empty-to-null'), None): cnv_boolean, + ((FORMNS,u'current-selected'), None): cnv_boolean, + ((FORMNS,u'current-state'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_date, +# ((FORMNS,u'current-value'), None): cnv_double, + ((FORMNS,u'current-value'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_time, + ((FORMNS,u'data-field'), None): cnv_string, + ((FORMNS,u'datasource'), None): cnv_string, + ((FORMNS,u'default-button'), None): cnv_boolean, + ((FORMNS,u'delay-for-repeat'), None): cnv_duration, + ((FORMNS,u'detail-fields'), None): cnv_string, + ((FORMNS,u'disabled'), None): cnv_boolean, + ((FORMNS,u'dropdown'), None): cnv_boolean, + ((FORMNS,u'echo-char'), None): cnv_string, + ((FORMNS,u'enctype'), None): cnv_string, + ((FORMNS,u'escape-processing'), None): cnv_boolean, + ((FORMNS,u'filter'), None): cnv_string, + ((FORMNS,u'focus-on-click'), None): cnv_boolean, + ((FORMNS,u'for'), None): cnv_string, + ((FORMNS,u'id'), None): cnv_ID, + ((FORMNS,u'ignore-result'), None): cnv_boolean, + ((FORMNS,u'image-align'), None): cnv_string, + ((FORMNS,u'image-data'), None): cnv_anyURI, + ((FORMNS,u'image-position'), None): cnv_string, + ((FORMNS,u'is-tristate'), None): cnv_boolean, + ((FORMNS,u'label'), None): cnv_string, + ((FORMNS,u'list-source'), None): cnv_string, + ((FORMNS,u'list-source-type'), None): cnv_string, + ((FORMNS,u'master-fields'), None): cnv_string, + ((FORMNS,u'max-length'), None): cnv_nonNegativeInteger, +# ((FORMNS,u'max-value'), None): cnv_date, +# ((FORMNS,u'max-value'), None): cnv_double, + ((FORMNS,u'max-value'), None): cnv_string, +# ((FORMNS,u'max-value'), None): cnv_time, + ((FORMNS,u'method'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_date, +# ((FORMNS,u'min-value'), None): cnv_double, + ((FORMNS,u'min-value'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_time, + ((FORMNS,u'multi-line'), None): cnv_boolean, + ((FORMNS,u'multiple'), None): cnv_boolean, + ((FORMNS,u'name'), None): cnv_string, + ((FORMNS,u'navigation-mode'), None): cnv_string, + ((FORMNS,u'order'), None): cnv_string, + ((FORMNS,u'orientation'), None): cnv_string, + ((FORMNS,u'page-step-size'), None): cnv_positiveInteger, + ((FORMNS,u'printable'), None): cnv_boolean, + ((FORMNS,u'property-name'), None): cnv_string, + ((FORMNS,u'readonly'), None): cnv_boolean, + ((FORMNS,u'selected'), None): cnv_boolean, + ((FORMNS,u'size'), None): cnv_nonNegativeInteger, + ((FORMNS,u'state'), None): cnv_string, + ((FORMNS,u'step-size'), None): cnv_positiveInteger, + ((FORMNS,u'tab-cycle'), None): cnv_string, + ((FORMNS,u'tab-index'), None): cnv_nonNegativeInteger, + ((FORMNS,u'tab-stop'), None): cnv_boolean, + ((FORMNS,u'text-style-name'), None): cnv_StyleNameRef, + ((FORMNS,u'title'), None): cnv_string, + ((FORMNS,u'toggle'), None): cnv_boolean, + ((FORMNS,u'validation'), None): cnv_boolean, +# ((FORMNS,u'value'), None): cnv_date, +# ((FORMNS,u'value'), None): cnv_double, + ((FORMNS,u'value'), None): cnv_string, +# ((FORMNS,u'value'), None): cnv_time, + ((FORMNS,u'visual-effect'), None): cnv_string, + ((FORMNS,u'xforms-list-source'), None): cnv_string, + ((FORMNS,u'xforms-submission'), None): cnv_string, + ((MANIFESTNS,'algorithm-name'), None): cnv_string, + ((MANIFESTNS,'checksum'), None): cnv_string, + ((MANIFESTNS,'checksum-type'), None): cnv_string, + ((MANIFESTNS,'full-path'), None): cnv_string, + ((MANIFESTNS,'initialisation-vector'), None): cnv_string, + ((MANIFESTNS,'iteration-count'), None): cnv_nonNegativeInteger, + ((MANIFESTNS,'key-derivation-name'), None): cnv_string, + ((MANIFESTNS,'manifest:media-type'), None): cnv_string, + ((MANIFESTNS,'salt'), None): cnv_string, + ((MANIFESTNS,'size'), None): cnv_nonNegativeInteger, + ((METANS,u'cell-count'), None): cnv_nonNegativeInteger, + ((METANS,u'character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'date'), None): cnv_dateTime, + ((METANS,u'delay'), None): cnv_duration, + ((METANS,u'draw-count'), None): cnv_nonNegativeInteger, + ((METANS,u'frame-count'), None): cnv_nonNegativeInteger, + ((METANS,u'image-count'), None): cnv_nonNegativeInteger, + ((METANS,u'name'), None): cnv_string, + ((METANS,u'non-whitespace-character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'ole-object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'page-count'), None): cnv_nonNegativeInteger, + ((METANS,u'paragraph-count'), None): cnv_nonNegativeInteger, + ((METANS,u'row-count'), None): cnv_nonNegativeInteger, + ((METANS,u'sentence-count'), None): cnv_nonNegativeInteger, + ((METANS,u'syllable-count'), None): cnv_nonNegativeInteger, + ((METANS,u'table-count'), None): cnv_nonNegativeInteger, + ((METANS,u'value-type'), None): cnv_metavaluetype, + ((METANS,u'word-count'), None): cnv_nonNegativeInteger, + ((NUMBERNS,u'automatic-order'), None): cnv_boolean, + ((NUMBERNS,u'calendar'), None): cnv_string, + ((NUMBERNS,u'country'), None): cnv_token, + ((NUMBERNS,u'decimal-places'), None): cnv_integer, + ((NUMBERNS,u'decimal-replacement'), None): cnv_string, + ((NUMBERNS,u'denominator-value'), None): cnv_integer, + ((NUMBERNS,u'display-factor'), None): cnv_double, + ((NUMBERNS,u'format-source'), None): cnv_string, + ((NUMBERNS,u'grouping'), None): cnv_boolean, + ((NUMBERNS,u'language'), None): cnv_token, + ((NUMBERNS,u'min-denominator-digits'), None): cnv_integer, + ((NUMBERNS,u'min-exponent-digits'), None): cnv_integer, + ((NUMBERNS,u'min-integer-digits'), None): cnv_integer, + ((NUMBERNS,u'min-numerator-digits'), None): cnv_integer, + ((NUMBERNS,u'position'), None): cnv_integer, + ((NUMBERNS,u'possessive-form'), None): cnv_boolean, + ((NUMBERNS,u'style'), None): cnv_string, + ((NUMBERNS,u'textual'), None): cnv_boolean, + ((NUMBERNS,u'title'), None): cnv_string, + ((NUMBERNS,u'transliteration-country'), None): cnv_token, + ((NUMBERNS,u'transliteration-format'), None): cnv_string, + ((NUMBERNS,u'transliteration-language'), None): cnv_token, + ((NUMBERNS,u'transliteration-style'), None): cnv_string, + ((NUMBERNS,u'truncate-on-overflow'), None): cnv_boolean, + ((OFFICENS,u'automatic-update'), None): cnv_boolean, + ((OFFICENS,u'boolean-value'), None): cnv_boolean, + ((OFFICENS,u'conversion-mode'), None): cnv_string, + ((OFFICENS,u'currency'), None): cnv_string, + ((OFFICENS,u'date-value'), None): cnv_dateTime, + ((OFFICENS,u'dde-application'), None): cnv_string, + ((OFFICENS,u'dde-item'), None): cnv_string, + ((OFFICENS,u'dde-topic'), None): cnv_string, + ((OFFICENS,u'display'), None): cnv_boolean, + ((OFFICENS,u'mimetype'), None): cnv_string, + ((OFFICENS,u'name'), None): cnv_string, + ((OFFICENS,u'process-content'), None): cnv_boolean, + ((OFFICENS,u'server-map'), None): cnv_boolean, + ((OFFICENS,u'string-value'), None): cnv_string, + ((OFFICENS,u'target-frame'), None): cnv_string, + ((OFFICENS,u'target-frame-name'), None): cnv_string, + ((OFFICENS,u'time-value'), None): cnv_duration, + ((OFFICENS,u'value'), None): cnv_double, + ((OFFICENS,u'value-type'), None): cnv_string, + ((OFFICENS,u'version'), None): cnv_string, + ((PRESENTATIONNS,u'action'), None): cnv_string, + ((PRESENTATIONNS,u'animations'), None): cnv_string, + ((PRESENTATIONNS,u'background-objects-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'background-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'class'), None): cnv_string, + ((PRESENTATIONNS,u'class-names'), None): cnv_NCNames, + ((PRESENTATIONNS,u'delay'), None): cnv_duration, + ((PRESENTATIONNS,u'direction'), None): cnv_string, + ((PRESENTATIONNS,u'display-date-time'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-footer'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-header'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-page-number'), None): cnv_boolean, + ((PRESENTATIONNS,u'duration'), None): cnv_string, + ((PRESENTATIONNS,u'effect'), None): cnv_string, + ((PRESENTATIONNS,u'endless'), None): cnv_boolean, + ((PRESENTATIONNS,u'force-manual'), None): cnv_boolean, + ((PRESENTATIONNS,u'full-screen'), None): cnv_boolean, + ((PRESENTATIONNS,u'group-id'), None): cnv_string, + ((PRESENTATIONNS,u'master-element'), None): cnv_IDREF, + ((PRESENTATIONNS,u'mouse-as-pen'), None): cnv_boolean, + ((PRESENTATIONNS,u'mouse-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'name'), None): cnv_string, + ((PRESENTATIONNS,u'node-type'), None): cnv_string, + ((PRESENTATIONNS,u'object'), None): cnv_string, + ((PRESENTATIONNS,u'pages'), None): cnv_string, + ((PRESENTATIONNS,u'path-id'), None): cnv_string, + ((PRESENTATIONNS,u'pause'), None): cnv_duration, + ((PRESENTATIONNS,u'placeholder'), None): cnv_boolean, + ((PRESENTATIONNS,u'play-full'), None): cnv_boolean, + ((PRESENTATIONNS,u'presentation-page-layout-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'preset-class'), None): cnv_string, + ((PRESENTATIONNS,u'preset-id'), None): cnv_string, + ((PRESENTATIONNS,u'preset-sub-type'), None): cnv_string, + ((PRESENTATIONNS,u'show'), None): cnv_string, + ((PRESENTATIONNS,u'show-logo'), None): cnv_boolean, + ((PRESENTATIONNS,u'source'), None): cnv_string, + ((PRESENTATIONNS,u'speed'), None): cnv_string, + ((PRESENTATIONNS,u'start-page'), None): cnv_string, + ((PRESENTATIONNS,u'start-scale'), None): cnv_string, + ((PRESENTATIONNS,u'start-with-navigator'), None): cnv_boolean, + ((PRESENTATIONNS,u'stay-on-top'), None): cnv_boolean, + ((PRESENTATIONNS,u'style-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'transition-on-click'), None): cnv_string, + ((PRESENTATIONNS,u'transition-speed'), None): cnv_string, + ((PRESENTATIONNS,u'transition-style'), None): cnv_string, + ((PRESENTATIONNS,u'transition-type'), None): cnv_string, + ((PRESENTATIONNS,u'use-date-time-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-footer-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-header-name'), None): cnv_string, + ((PRESENTATIONNS,u'user-transformed'), None): cnv_boolean, + ((PRESENTATIONNS,u'verb'), None): cnv_nonNegativeInteger, + ((PRESENTATIONNS,u'visibility'), None): cnv_string, + ((SCRIPTNS,u'event-name'), None): cnv_string, + ((SCRIPTNS,u'language'), None): cnv_string, + ((SCRIPTNS,u'macro-name'), None): cnv_string, + ((SMILNS,u'accelerate'), None): cnv_double, + ((SMILNS,u'accumulate'), None): cnv_string, + ((SMILNS,u'additive'), None): cnv_string, + ((SMILNS,u'attributeName'), None): cnv_string, + ((SMILNS,u'autoReverse'), None): cnv_boolean, + ((SMILNS,u'begin'), None): cnv_string, + ((SMILNS,u'by'), None): cnv_string, + ((SMILNS,u'calcMode'), None): cnv_string, + ((SMILNS,u'decelerate'), None): cnv_double, + ((SMILNS,u'direction'), None): cnv_string, + ((SMILNS,u'dur'), None): cnv_string, + ((SMILNS,u'end'), None): cnv_string, + ((SMILNS,u'endsync'), None): cnv_string, + ((SMILNS,u'fadeColor'), None): cnv_string, + ((SMILNS,u'fill'), None): cnv_string, + ((SMILNS,u'fillDefault'), None): cnv_string, + ((SMILNS,u'from'), None): cnv_string, + ((SMILNS,u'keySplines'), None): cnv_string, + ((SMILNS,u'keyTimes'), None): cnv_string, + ((SMILNS,u'mode'), None): cnv_string, + ((SMILNS,u'repeatCount'), None): cnv_nonNegativeInteger, + ((SMILNS,u'repeatDur'), None): cnv_string, + ((SMILNS,u'restart'), None): cnv_string, + ((SMILNS,u'restartDefault'), None): cnv_string, + ((SMILNS,u'subtype'), None): cnv_string, + ((SMILNS,u'targetElement'), None): cnv_IDREF, + ((SMILNS,u'to'), None): cnv_string, + ((SMILNS,u'type'), None): cnv_string, + ((SMILNS,u'values'), None): cnv_string, + ((STYLENS,u'adjustment'), None): cnv_string, + ((STYLENS,u'apply-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'auto-text-indent'), None): cnv_boolean, + ((STYLENS,u'auto-update'), None): cnv_boolean, + ((STYLENS,u'background-transparency'), None): cnv_string, + ((STYLENS,u'base-cell-address'), None): cnv_string, + ((STYLENS,u'border-line-width-bottom'), None): cnv_string, + ((STYLENS,u'border-line-width'), None): cnv_string, + ((STYLENS,u'border-line-width-left'), None): cnv_string, + ((STYLENS,u'border-line-width-right'), None): cnv_string, + ((STYLENS,u'border-line-width-top'), None): cnv_string, + ((STYLENS,u'cell-protect'), None): cnv_string, + ((STYLENS,u'char'), None): cnv_string, + ((STYLENS,u'class'), None): cnv_string, + ((STYLENS,u'color'), None): cnv_string, + ((STYLENS,u'column-width'), None): cnv_string, + ((STYLENS,u'condition'), None): cnv_string, + ((STYLENS,u'country-asian'), None): cnv_string, + ((STYLENS,u'country-complex'), None): cnv_string, + ((STYLENS,u'data-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'decimal-places'), None): cnv_string, + ((STYLENS,u'default-outline-level'), None): cnv_positiveInteger, + ((STYLENS,u'diagonal-bl-tr'), None): cnv_string, + ((STYLENS,u'diagonal-bl-tr-widths'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br-widths'), None): cnv_string, + ((STYLENS,u'direction'), None): cnv_string, + ((STYLENS,u'display'), None): cnv_boolean, + ((STYLENS,u'display-name'), None): cnv_string, + ((STYLENS,u'distance-after-sep'), None): cnv_length, + ((STYLENS,u'distance-before-sep'), None): cnv_length, + ((STYLENS,u'distance'), None): cnv_length, + ((STYLENS,u'dynamic-spacing'), None): cnv_boolean, + ((STYLENS,u'editable'), None): cnv_boolean, + ((STYLENS,u'family'), None): cnv_family, + ((STYLENS,u'filter-name'), None): cnv_string, + ((STYLENS,u'first-page-number'), None): cnv_string, + ((STYLENS,u'flow-with-text'), None): cnv_boolean, + ((STYLENS,u'font-adornments'), None): cnv_string, + ((STYLENS,u'font-charset'), None): cnv_string, + ((STYLENS,u'font-family-asian'), None): cnv_string, + ((STYLENS,u'font-family-complex'), None): cnv_string, + ((STYLENS,u'font-family-generic-asian'), None): cnv_string, + ((STYLENS,u'font-family-generic'), None): cnv_string, + ((STYLENS,u'font-family-generic-complex'), None): cnv_string, + ((STYLENS,u'font-independent-line-spacing'), None): cnv_boolean, + ((STYLENS,u'font-name-asian'), None): cnv_string, + ((STYLENS,u'font-name'), None): cnv_string, + ((STYLENS,u'font-name-complex'), None): cnv_string, + ((STYLENS,u'font-pitch-asian'), None): cnv_string, + ((STYLENS,u'font-pitch'), None): cnv_string, + ((STYLENS,u'font-pitch-complex'), None): cnv_string, + ((STYLENS,u'font-relief'), None): cnv_string, + ((STYLENS,u'font-size-asian'), None): cnv_string, + ((STYLENS,u'font-size-complex'), None): cnv_string, + ((STYLENS,u'font-size-rel-asian'), None): cnv_length, + ((STYLENS,u'font-size-rel'), None): cnv_length, + ((STYLENS,u'font-size-rel-complex'), None): cnv_length, + ((STYLENS,u'font-style-asian'), None): cnv_string, + ((STYLENS,u'font-style-complex'), None): cnv_string, + ((STYLENS,u'font-style-name-asian'), None): cnv_string, + ((STYLENS,u'font-style-name'), None): cnv_string, + ((STYLENS,u'font-style-name-complex'), None): cnv_string, + ((STYLENS,u'font-weight-asian'), None): cnv_string, + ((STYLENS,u'font-weight-complex'), None): cnv_string, + ((STYLENS,u'footnote-max-height'), None): cnv_length, + ((STYLENS,u'glyph-orientation-vertical'), None): cnv_string, + ((STYLENS,u'height'), None): cnv_string, + ((STYLENS,u'horizontal-pos'), None): cnv_string, + ((STYLENS,u'horizontal-rel'), None): cnv_string, + ((STYLENS,u'justify-single-word'), None): cnv_boolean, + ((STYLENS,u'language-asian'), None): cnv_string, + ((STYLENS,u'language-complex'), None): cnv_string, + ((STYLENS,u'layout-grid-base-height'), None): cnv_length, + ((STYLENS,u'layout-grid-color'), None): cnv_string, + ((STYLENS,u'layout-grid-display'), None): cnv_boolean, + ((STYLENS,u'layout-grid-lines'), None): cnv_string, + ((STYLENS,u'layout-grid-mode'), None): cnv_string, + ((STYLENS,u'layout-grid-print'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-below'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-height'), None): cnv_length, + ((STYLENS,u'leader-char'), None): cnv_string, + ((STYLENS,u'leader-color'), None): cnv_string, + ((STYLENS,u'leader-style'), None): cnv_string, + ((STYLENS,u'leader-text'), None): cnv_string, + ((STYLENS,u'leader-text-style'), None): cnv_StyleNameRef, + ((STYLENS,u'leader-type'), None): cnv_string, + ((STYLENS,u'leader-width'), None): cnv_string, + ((STYLENS,u'legend-expansion-aspect-ratio'), None): cnv_double, + ((STYLENS,u'legend-expansion'), None): cnv_string, + ((STYLENS,u'length'), None): cnv_positiveInteger, + ((STYLENS,u'letter-kerning'), None): cnv_boolean, + ((STYLENS,u'line-break'), None): cnv_string, + ((STYLENS,u'line-height-at-least'), None): cnv_string, + ((STYLENS,u'line-spacing'), None): cnv_length, + ((STYLENS,u'line-style'), None): cnv_string, + ((STYLENS,u'lines'), None): cnv_positiveInteger, + ((STYLENS,u'list-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'master-page-name'), None): cnv_StyleNameRef, + ((STYLENS,u'may-break-between-rows'), None): cnv_boolean, + ((STYLENS,u'min-row-height'), None): cnv_string, + ((STYLENS,u'mirror'), None): cnv_string, + ((STYLENS,u'name'), None): cnv_NCName, + ((STYLENS,u'name'), (STYLENS,u'font-face')): cnv_string, + ((STYLENS,u'next-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'num-format'), None): cnv_string, + ((STYLENS,u'num-letter-sync'), None): cnv_boolean, + ((STYLENS,u'num-prefix'), None): cnv_string, + ((STYLENS,u'num-suffix'), None): cnv_string, + ((STYLENS,u'number-wrapped-paragraphs'), None): cnv_string, + ((STYLENS,u'overflow-behavior'), None): cnv_string, + ((STYLENS,u'page-layout-name'), None): cnv_StyleNameRef, + ((STYLENS,u'page-number'), None): cnv_string, + ((STYLENS,u'page-usage'), None): cnv_string, + ((STYLENS,u'paper-tray-name'), None): cnv_string, + ((STYLENS,u'parent-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'position'), None): cnv_position, + ((STYLENS,u'print'), None): cnv_string, + ((STYLENS,u'print-content'), None): cnv_boolean, + ((STYLENS,u'print-orientation'), None): cnv_string, + ((STYLENS,u'print-page-order'), None): cnv_string, + ((STYLENS,u'protect'), None): cnv_boolean, + ((STYLENS,u'punctuation-wrap'), None): cnv_string, + ((STYLENS,u'register-true'), None): cnv_boolean, + ((STYLENS,u'register-truth-ref-style-name'), None): cnv_string, + ((STYLENS,u'rel-column-width'), None): cnv_string, + ((STYLENS,u'rel-height'), None): cnv_string, + ((STYLENS,u'rel-width'), None): cnv_string, + ((STYLENS,u'repeat'), None): cnv_string, + ((STYLENS,u'repeat-content'), None): cnv_boolean, + ((STYLENS,u'rotation-align'), None): cnv_string, + ((STYLENS,u'rotation-angle'), None): cnv_string, + ((STYLENS,u'row-height'), None): cnv_string, + ((STYLENS,u'ruby-align'), None): cnv_string, + ((STYLENS,u'ruby-position'), None): cnv_string, + ((STYLENS,u'run-through'), None): cnv_string, + ((STYLENS,u'scale-to'), None): cnv_string, + ((STYLENS,u'scale-to-pages'), None): cnv_string, + ((STYLENS,u'script-type'), None): cnv_string, + ((STYLENS,u'shadow'), None): cnv_string, + ((STYLENS,u'shrink-to-fit'), None): cnv_boolean, + ((STYLENS,u'snap-to-layout-grid'), None): cnv_boolean, + ((STYLENS,u'style'), None): cnv_string, + ((STYLENS,u'style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'tab-stop-distance'), None): cnv_string, + ((STYLENS,u'table-centering'), None): cnv_string, + ((STYLENS,u'text-align-source'), None): cnv_string, + ((STYLENS,u'text-autospace'), None): cnv_string, + ((STYLENS,u'text-blinking'), None): cnv_boolean, + ((STYLENS,u'text-combine'), None): cnv_string, + ((STYLENS,u'text-combine-end-char'), None): cnv_string, + ((STYLENS,u'text-combine-start-char'), None): cnv_string, + ((STYLENS,u'text-emphasize'), None): cnv_string, + ((STYLENS,u'text-line-through-color'), None): cnv_string, + ((STYLENS,u'text-line-through-mode'), None): cnv_string, + ((STYLENS,u'text-line-through-style'), None): cnv_string, + ((STYLENS,u'text-line-through-text'), None): cnv_string, + ((STYLENS,u'text-line-through-text-style'), None): cnv_string, + ((STYLENS,u'text-line-through-type'), None): cnv_string, + ((STYLENS,u'text-line-through-width'), None): cnv_string, + ((STYLENS,u'text-outline'), None): cnv_boolean, + ((STYLENS,u'text-position'), None): cnv_string, + ((STYLENS,u'text-rotation-angle'), None): cnv_string, + ((STYLENS,u'text-rotation-scale'), None): cnv_string, + ((STYLENS,u'text-scale'), None): cnv_string, + ((STYLENS,u'text-underline-color'), None): cnv_string, + ((STYLENS,u'text-underline-mode'), None): cnv_string, + ((STYLENS,u'text-underline-style'), None): cnv_string, + ((STYLENS,u'text-underline-type'), None): cnv_string, + ((STYLENS,u'text-underline-width'), None): cnv_string, + ((STYLENS,u'type'), None): cnv_string, + ((STYLENS,u'use-optimal-column-width'), None): cnv_boolean, + ((STYLENS,u'use-optimal-row-height'), None): cnv_boolean, + ((STYLENS,u'use-window-font-color'), None): cnv_boolean, + ((STYLENS,u'vertical-align'), None): cnv_string, + ((STYLENS,u'vertical-pos'), None): cnv_string, + ((STYLENS,u'vertical-rel'), None): cnv_string, + ((STYLENS,u'volatile'), None): cnv_boolean, + ((STYLENS,u'width'), None): cnv_string, + ((STYLENS,u'wrap'), None): cnv_string, + ((STYLENS,u'wrap-contour'), None): cnv_boolean, + ((STYLENS,u'wrap-contour-mode'), None): cnv_string, + ((STYLENS,u'wrap-dynamic-treshold'), None): cnv_string, + ((STYLENS,u'writing-mode-automatic'), None): cnv_boolean, + ((STYLENS,u'writing-mode'), None): cnv_string, + ((SVGNS,u'accent-height'), None): cnv_integer, + ((SVGNS,u'alphabetic'), None): cnv_integer, + ((SVGNS,u'ascent'), None): cnv_integer, + ((SVGNS,u'bbox'), None): cnv_string, + ((SVGNS,u'cap-height'), None): cnv_integer, + ((SVGNS,u'cx'), None): cnv_string, + ((SVGNS,u'cy'), None): cnv_string, + ((SVGNS,u'd'), None): cnv_string, + ((SVGNS,u'descent'), None): cnv_integer, + ((SVGNS,u'fill-rule'), None): cnv_string, + ((SVGNS,u'font-family'), None): cnv_string, + ((SVGNS,u'font-size'), None): cnv_string, + ((SVGNS,u'font-stretch'), None): cnv_string, + ((SVGNS,u'font-style'), None): cnv_string, + ((SVGNS,u'font-variant'), None): cnv_string, + ((SVGNS,u'font-weight'), None): cnv_string, + ((SVGNS,u'fx'), None): cnv_string, + ((SVGNS,u'fy'), None): cnv_string, + ((SVGNS,u'gradientTransform'), None): cnv_string, + ((SVGNS,u'gradientUnits'), None): cnv_string, + ((SVGNS,u'hanging'), None): cnv_integer, + ((SVGNS,u'height'), None): cnv_length, + ((SVGNS,u'ideographic'), None): cnv_integer, + ((SVGNS,u'mathematical'), None): cnv_integer, + ((SVGNS,u'name'), None): cnv_string, + ((SVGNS,u'offset'), None): cnv_string, + ((SVGNS,u'origin'), None): cnv_string, + ((SVGNS,u'overline-position'), None): cnv_integer, + ((SVGNS,u'overline-thickness'), None): cnv_integer, + ((SVGNS,u'panose-1'), None): cnv_string, + ((SVGNS,u'path'), None): cnv_string, + ((SVGNS,u'r'), None): cnv_length, + ((SVGNS,u'rx'), None): cnv_length, + ((SVGNS,u'ry'), None): cnv_length, + ((SVGNS,u'slope'), None): cnv_integer, + ((SVGNS,u'spreadMethod'), None): cnv_string, + ((SVGNS,u'stemh'), None): cnv_integer, + ((SVGNS,u'stemv'), None): cnv_integer, + ((SVGNS,u'stop-color'), None): cnv_string, + ((SVGNS,u'stop-opacity'), None): cnv_double, + ((SVGNS,u'strikethrough-position'), None): cnv_integer, + ((SVGNS,u'strikethrough-thickness'), None): cnv_integer, + ((SVGNS,u'string'), None): cnv_string, + ((SVGNS,u'stroke-color'), None): cnv_string, + ((SVGNS,u'stroke-opacity'), None): cnv_string, + ((SVGNS,u'stroke-width'), None): cnv_length, + ((SVGNS,u'type'), None): cnv_string, + ((SVGNS,u'underline-position'), None): cnv_integer, + ((SVGNS,u'underline-thickness'), None): cnv_integer, + ((SVGNS,u'unicode-range'), None): cnv_string, + ((SVGNS,u'units-per-em'), None): cnv_integer, + ((SVGNS,u'v-alphabetic'), None): cnv_integer, + ((SVGNS,u'v-hanging'), None): cnv_integer, + ((SVGNS,u'v-ideographic'), None): cnv_integer, + ((SVGNS,u'v-mathematical'), None): cnv_integer, + ((SVGNS,u'viewBox'), None): cnv_viewbox, + ((SVGNS,u'width'), None): cnv_length, + ((SVGNS,u'widths'), None): cnv_string, + ((SVGNS,u'x'), None): cnv_length, + ((SVGNS,u'x-height'), None): cnv_integer, + ((SVGNS,u'x1'), None): cnv_lengthorpercent, + ((SVGNS,u'x2'), None): cnv_lengthorpercent, + ((SVGNS,u'y'), None): cnv_length, + ((SVGNS,u'y1'), None): cnv_lengthorpercent, + ((SVGNS,u'y2'), None): cnv_lengthorpercent, + ((TABLENS,u'acceptance-state'), None): cnv_string, + ((TABLENS,u'add-empty-lines'), None): cnv_boolean, + ((TABLENS,u'algorithm'), None): cnv_string, + ((TABLENS,u'align'), None): cnv_string, + ((TABLENS,u'allow-empty-cell'), None): cnv_boolean, + ((TABLENS,u'application-data'), None): cnv_string, + ((TABLENS,u'automatic-find-labels'), None): cnv_boolean, + ((TABLENS,u'base-cell-address'), None): cnv_string, + ((TABLENS,u'bind-styles-to-content'), None): cnv_boolean, + ((TABLENS,u'border-color'), None): cnv_string, + ((TABLENS,u'border-model'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'case-sensitive'), None): cnv_boolean, + ((TABLENS,u'case-sensitive'), None): cnv_string, + ((TABLENS,u'cell-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range'), None): cnv_string, + ((TABLENS,u'column'), None): cnv_integer, + ((TABLENS,u'comment'), None): cnv_string, + ((TABLENS,u'condition'), None): cnv_string, + ((TABLENS,u'condition-source'), None): cnv_string, + ((TABLENS,u'condition-source-range-address'), None): cnv_string, + ((TABLENS,u'contains-error'), None): cnv_boolean, + ((TABLENS,u'contains-header'), None): cnv_boolean, + ((TABLENS,u'content-validation-name'), None): cnv_string, + ((TABLENS,u'copy-back'), None): cnv_boolean, + ((TABLENS,u'copy-formulas'), None): cnv_boolean, + ((TABLENS,u'copy-styles'), None): cnv_boolean, + ((TABLENS,u'count'), None): cnv_positiveInteger, + ((TABLENS,u'country'), None): cnv_token, + ((TABLENS,u'data-cell-range-address'), None): cnv_string, + ((TABLENS,u'data-field'), None): cnv_string, + ((TABLENS,u'data-type'), None): cnv_string, + ((TABLENS,u'database-name'), None): cnv_string, + ((TABLENS,u'database-table-name'), None): cnv_string, + ((TABLENS,u'date-end'), None): cnv_string, + ((TABLENS,u'date-start'), None): cnv_string, + ((TABLENS,u'date-value-type'), None): cnv_date, + ((TABLENS,u'default-cell-style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'direction'), None): cnv_string, + ((TABLENS,u'display-border'), None): cnv_boolean, + ((TABLENS,u'display'), None): cnv_boolean, + ((TABLENS,u'display-duplicates'), None): cnv_boolean, + ((TABLENS,u'display-filter-buttons'), None): cnv_boolean, + ((TABLENS,u'display-list'), None): cnv_string, + ((TABLENS,u'display-member-mode'), None): cnv_string, + ((TABLENS,u'drill-down-on-double-click'), None): cnv_boolean, + ((TABLENS,u'enabled'), None): cnv_boolean, + ((TABLENS,u'end-cell-address'), None): cnv_string, + ((TABLENS,u'end'), None): cnv_string, + ((TABLENS,u'end-column'), None): cnv_integer, + ((TABLENS,u'end-position'), None): cnv_integer, + ((TABLENS,u'end-row'), None): cnv_integer, + ((TABLENS,u'end-table'), None): cnv_integer, + ((TABLENS,u'end-x'), None): cnv_length, + ((TABLENS,u'end-y'), None): cnv_length, + ((TABLENS,u'execute'), None): cnv_boolean, + ((TABLENS,u'expression'), None): cnv_string, + ((TABLENS,u'field-name'), None): cnv_string, + ((TABLENS,u'field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'field-number'), None): cnv_string, + ((TABLENS,u'filter-name'), None): cnv_string, + ((TABLENS,u'filter-options'), None): cnv_string, + ((TABLENS,u'formula'), None): cnv_string, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'grand-total'), None): cnv_string, + ((TABLENS,u'group-by-field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'grouped-by'), None): cnv_string, + ((TABLENS,u'has-persistent-data'), None): cnv_boolean, + ((TABLENS,u'id'), None): cnv_string, + ((TABLENS,u'identify-categories'), None): cnv_boolean, + ((TABLENS,u'ignore-empty-rows'), None): cnv_boolean, + ((TABLENS,u'index'), None): cnv_nonNegativeInteger, + ((TABLENS,u'is-active'), None): cnv_boolean, + ((TABLENS,u'is-data-layout-field'), None): cnv_string, + ((TABLENS,u'is-selection'), None): cnv_boolean, + ((TABLENS,u'is-sub-table'), None): cnv_boolean, + ((TABLENS,u'label-cell-range-address'), None): cnv_string, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'last-column-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'last-row-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'layout-mode'), None): cnv_string, + ((TABLENS,u'link-to-source-data'), None): cnv_boolean, + ((TABLENS,u'marked-invalid'), None): cnv_boolean, + ((TABLENS,u'matrix-covered'), None): cnv_boolean, + ((TABLENS,u'maximum-difference'), None): cnv_double, + ((TABLENS,u'member-count'), None): cnv_nonNegativeInteger, + ((TABLENS,u'member-name'), None): cnv_string, + ((TABLENS,u'member-type'), None): cnv_string, + ((TABLENS,u'message-type'), None): cnv_string, + ((TABLENS,u'mode'), None): cnv_string, + ((TABLENS,u'multi-deletion-spanned'), None): cnv_integer, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'null-year'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'object-name'), None): cnv_string, + ((TABLENS,u'on-update-keep-size'), None): cnv_boolean, + ((TABLENS,u'on-update-keep-styles'), None): cnv_boolean, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'order'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'page-breaks-on-group-change'), None): cnv_boolean, + ((TABLENS,u'parse-sql-statement'), None): cnv_boolean, + ((TABLENS,u'password'), None): cnv_string, + ((TABLENS,u'position'), None): cnv_integer, + ((TABLENS,u'precision-as-shown'), None): cnv_boolean, + ((TABLENS,u'print'), None): cnv_boolean, + ((TABLENS,u'print-ranges'), None): cnv_string, + ((TABLENS,u'protect'), None): cnv_boolean, + ((TABLENS,u'protected'), None): cnv_boolean, + ((TABLENS,u'protection-key'), None): cnv_string, + ((TABLENS,u'query-name'), None): cnv_string, + ((TABLENS,u'range-usable-as'), None): cnv_string, + ((TABLENS,u'refresh-delay'), None): cnv_boolean, + ((TABLENS,u'refresh-delay'), None): cnv_duration, + ((TABLENS,u'rejecting-change-id'), None): cnv_string, + ((TABLENS,u'row'), None): cnv_integer, + ((TABLENS,u'scenario-ranges'), None): cnv_string, + ((TABLENS,u'search-criteria-must-apply-to-whole-cell'), None): cnv_boolean, + ((TABLENS,u'selected-page'), None): cnv_string, + ((TABLENS,u'show-details'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_string, + ((TABLENS,u'show-filter-button'), None): cnv_boolean, + ((TABLENS,u'sort-mode'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-name'), None): cnv_string, + ((TABLENS,u'sql-statement'), None): cnv_string, + ((TABLENS,u'start'), None): cnv_string, + ((TABLENS,u'start-column'), None): cnv_integer, + ((TABLENS,u'start-position'), None): cnv_integer, + ((TABLENS,u'start-row'), None): cnv_integer, + ((TABLENS,u'start-table'), None): cnv_integer, + ((TABLENS,u'status'), None): cnv_string, + ((TABLENS,u'step'), None): cnv_double, + ((TABLENS,u'steps'), None): cnv_positiveInteger, + ((TABLENS,u'structure-protected'), None): cnv_boolean, + ((TABLENS,u'style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'table-background'), None): cnv_boolean, + ((TABLENS,u'table'), None): cnv_integer, + ((TABLENS,u'table-name'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'title'), None): cnv_string, + ((TABLENS,u'track-changes'), None): cnv_boolean, + ((TABLENS,u'type'), None): cnv_string, + ((TABLENS,u'use-labels'), None): cnv_string, + ((TABLENS,u'use-regular-expressions'), None): cnv_boolean, + ((TABLENS,u'used-hierarchy'), None): cnv_integer, + ((TABLENS,u'user-name'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value-type'), None): cnv_string, + ((TABLENS,u'visibility'), None): cnv_string, + ((TEXTNS,u'active'), None): cnv_boolean, + ((TEXTNS,u'address'), None): cnv_string, + ((TEXTNS,u'alphabetical-separators'), None): cnv_boolean, + ((TEXTNS,u'anchor-page-number'), None): cnv_positiveInteger, + ((TEXTNS,u'anchor-type'), None): cnv_string, + ((TEXTNS,u'animation'), None): cnv_string, + ((TEXTNS,u'animation-delay'), None): cnv_string, + ((TEXTNS,u'animation-direction'), None): cnv_string, + ((TEXTNS,u'animation-repeat'), None): cnv_string, + ((TEXTNS,u'animation-start-inside'), None): cnv_boolean, + ((TEXTNS,u'animation-steps'), None): cnv_length, + ((TEXTNS,u'animation-stop-inside'), None): cnv_boolean, + ((TEXTNS,u'annote'), None): cnv_string, + ((TEXTNS,u'author'), None): cnv_string, + ((TEXTNS,u'bibliography-data-field'), None): cnv_string, + ((TEXTNS,u'bibliography-type'), None): cnv_string, + ((TEXTNS,u'booktitle'), None): cnv_string, + ((TEXTNS,u'bullet-char'), None): cnv_string, + ((TEXTNS,u'bullet-relative-size'), None): cnv_string, + ((TEXTNS,u'c'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'capitalize-entries'), None): cnv_boolean, + ((TEXTNS,u'caption-sequence-format'), None): cnv_string, + ((TEXTNS,u'caption-sequence-name'), None): cnv_string, + ((TEXTNS,u'change-id'), None): cnv_IDREF, + ((TEXTNS,u'chapter'), None): cnv_string, + ((TEXTNS,u'citation-body-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'citation-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'class-names'), None): cnv_NCNames, + ((TEXTNS,u'column-name'), None): cnv_string, + ((TEXTNS,u'combine-entries'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-dash'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-pp'), None): cnv_boolean, + ((TEXTNS,u'comma-separated'), None): cnv_boolean, + ((TEXTNS,u'cond-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'condition'), None): cnv_string, + ((TEXTNS,u'connection-name'), None): cnv_string, + ((TEXTNS,u'consecutive-numbering'), None): cnv_boolean, + ((TEXTNS,u'continue-numbering'), None): cnv_boolean, + ((TEXTNS,u'copy-outline-levels'), None): cnv_boolean, + ((TEXTNS,u'count-empty-lines'), None): cnv_boolean, + ((TEXTNS,u'count-in-text-boxes'), None): cnv_boolean, + ((TEXTNS,u'current-value'), None): cnv_boolean, + ((TEXTNS,u'custom1'), None): cnv_string, + ((TEXTNS,u'custom2'), None): cnv_string, + ((TEXTNS,u'custom3'), None): cnv_string, + ((TEXTNS,u'custom4'), None): cnv_string, + ((TEXTNS,u'custom5'), None): cnv_string, + ((TEXTNS,u'database-name'), None): cnv_string, + ((TEXTNS,u'date-adjust'), None): cnv_duration, + ((TEXTNS,u'date-value'), None): cnv_date, + ((TEXTNS,u'date-value'), None): cnv_dateTime, + ((TEXTNS,u'default-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'description'), None): cnv_string, + ((TEXTNS,u'display'), None): cnv_string, + ((TEXTNS,u'display-levels'), None): cnv_positiveInteger, + ((TEXTNS,u'display-outline-level'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'dont-balance-text-columns'), None): cnv_boolean, + ((TEXTNS,u'duration'), None): cnv_duration, + ((TEXTNS,u'edition'), None): cnv_string, + ((TEXTNS,u'editor'), None): cnv_string, + ((TEXTNS,u'filter-name'), None): cnv_string, + ((TEXTNS,u'first-row-end-column'), None): cnv_string, + ((TEXTNS,u'first-row-start-column'), None): cnv_string, + ((TEXTNS,u'fixed'), None): cnv_boolean, + ((TEXTNS,u'footnotes-position'), None): cnv_string, + ((TEXTNS,u'formula'), None): cnv_string, + ((TEXTNS,u'global'), None): cnv_boolean, + ((TEXTNS,u'howpublished'), None): cnv_string, + ((TEXTNS,u'id'), None): cnv_ID, +# ((TEXTNS,u'id'), None): cnv_string, + ((TEXTNS,u'identifier'), None): cnv_string, + ((TEXTNS,u'ignore-case'), None): cnv_boolean, + ((TEXTNS,u'increment'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'index-name'), None): cnv_string, + ((TEXTNS,u'index-scope'), None): cnv_string, + ((TEXTNS,u'institution'), None): cnv_string, + ((TEXTNS,u'is-hidden'), None): cnv_boolean, + ((TEXTNS,u'is-list-header'), None): cnv_boolean, + ((TEXTNS,u'isbn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'journal'), None): cnv_string, + ((TEXTNS,u'key'), None): cnv_string, + ((TEXTNS,u'key1'), None): cnv_string, + ((TEXTNS,u'key1-phonetic'), None): cnv_string, + ((TEXTNS,u'key2'), None): cnv_string, + ((TEXTNS,u'key2-phonetic'), None): cnv_string, + ((TEXTNS,u'kind'), None): cnv_string, + ((TEXTNS,u'label'), None): cnv_string, + ((TEXTNS,u'last-row-end-column'), None): cnv_string, + ((TEXTNS,u'last-row-start-column'), None): cnv_string, + ((TEXTNS,u'level'), None): cnv_positiveInteger, + ((TEXTNS,u'line-break'), None): cnv_boolean, + ((TEXTNS,u'line-number'), None): cnv_string, + ((TEXTNS,u'main-entry'), None): cnv_boolean, + ((TEXTNS,u'main-entry-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'master-page-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'min-label-distance'), None): cnv_string, + ((TEXTNS,u'min-label-width'), None): cnv_string, + ((TEXTNS,u'month'), None): cnv_string, + ((TEXTNS,u'name'), None): cnv_string, + ((TEXTNS,u'note-class'), None): cnv_textnoteclass, + ((TEXTNS,u'note'), None): cnv_string, + ((TEXTNS,u'number'), None): cnv_string, + ((TEXTNS,u'number-lines'), None): cnv_boolean, + ((TEXTNS,u'number-position'), None): cnv_string, + ((TEXTNS,u'numbered-entries'), None): cnv_boolean, + ((TEXTNS,u'offset'), None): cnv_string, + ((TEXTNS,u'organizations'), None): cnv_string, + ((TEXTNS,u'outline-level'), None): cnv_string, + ((TEXTNS,u'page-adjust'), None): cnv_integer, + ((TEXTNS,u'pages'), None): cnv_string, + ((TEXTNS,u'placeholder-type'), None): cnv_string, + ((TEXTNS,u'prefix'), None): cnv_string, + ((TEXTNS,u'protected'), None): cnv_boolean, + ((TEXTNS,u'protection-key'), None): cnv_string, + ((TEXTNS,u'publisher'), None): cnv_string, + ((TEXTNS,u'ref-name'), None): cnv_string, + ((TEXTNS,u'reference-format'), None): cnv_string, + ((TEXTNS,u'relative-tab-stop-position'), None): cnv_boolean, + ((TEXTNS,u'report-type'), None): cnv_string, + ((TEXTNS,u'restart-numbering'), None): cnv_boolean, + ((TEXTNS,u'restart-on-page'), None): cnv_boolean, + ((TEXTNS,u'row-number'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'school'), None): cnv_string, + ((TEXTNS,u'section-name'), None): cnv_string, + ((TEXTNS,u'select-page'), None): cnv_string, + ((TEXTNS,u'separation-character'), None): cnv_string, + ((TEXTNS,u'series'), None): cnv_string, + ((TEXTNS,u'sort-algorithm'), None): cnv_string, + ((TEXTNS,u'sort-ascending'), None): cnv_boolean, + ((TEXTNS,u'sort-by-position'), None): cnv_boolean, + ((TEXTNS,u'space-before'), None): cnv_string, + ((TEXTNS,u'start-numbering-at'), None): cnv_string, + ((TEXTNS,u'start-value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'start-value'), None): cnv_positiveInteger, + ((TEXTNS,u'string-value'), None): cnv_string, + ((TEXTNS,u'string-value-if-false'), None): cnv_string, + ((TEXTNS,u'string-value-if-true'), None): cnv_string, + ((TEXTNS,u'string-value-phonetic'), None): cnv_string, + ((TEXTNS,u'style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'suffix'), None): cnv_string, + ((TEXTNS,u'tab-ref'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'table-name'), None): cnv_string, + ((TEXTNS,u'table-type'), None): cnv_string, + ((TEXTNS,u'time-adjust'), None): cnv_duration, + ((TEXTNS,u'time-value'), None): cnv_dateTime, + ((TEXTNS,u'time-value'), None): cnv_time, + ((TEXTNS,u'title'), None): cnv_string, + ((TEXTNS,u'track-changes'), None): cnv_boolean, + ((TEXTNS,u'url'), None): cnv_string, + ((TEXTNS,u'use-caption'), None): cnv_boolean, + ((TEXTNS,u'use-chart-objects'), None): cnv_boolean, + ((TEXTNS,u'use-draw-objects'), None): cnv_boolean, + ((TEXTNS,u'use-floating-frames'), None): cnv_boolean, + ((TEXTNS,u'use-graphics'), None): cnv_boolean, + ((TEXTNS,u'use-index-marks'), None): cnv_boolean, + ((TEXTNS,u'use-index-source-styles'), None): cnv_boolean, + ((TEXTNS,u'use-keys-as-entries'), None): cnv_boolean, + ((TEXTNS,u'use-math-objects'), None): cnv_boolean, + ((TEXTNS,u'use-objects'), None): cnv_boolean, + ((TEXTNS,u'use-other-objects'), None): cnv_boolean, + ((TEXTNS,u'use-outline-level'), None): cnv_boolean, + ((TEXTNS,u'use-spreadsheet-objects'), None): cnv_boolean, + ((TEXTNS,u'use-tables'), None): cnv_boolean, + ((TEXTNS,u'value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'visited-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'volume'), None): cnv_string, + ((TEXTNS,u'year'), None): cnv_string, + ((XFORMSNS,u'bind'), None): cnv_string, + ((XLINKNS,u'actuate'), None): cnv_string, + ((XLINKNS,u'href'), None): cnv_anyURI, + ((XLINKNS,u'show'), None): cnv_xlinkshow, + ((XLINKNS,u'title'), None): cnv_string, + ((XLINKNS,u'type'), None): cnv_string, +} + +class AttrConverters: + def convert(self, attribute, value, element): + conversion = attrconverters.get((attribute,element), None) + if conversion is not None: + return conversion(attribute, value, element) + else: + conversion = attrconverters.get((attribute, None), None) + if conversion is not None: + return conversion(attribute, value, element) + return unicode(value) + diff --git a/src/odf/chart.py b/src/odf/chart.py new file mode 100644 index 0000000000..cca83961ac --- /dev/null +++ b/src/odf/chart.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import CHARTNS +from element import Element + +# Autogenerated +def Axis(**args): + return Element(qname = (CHARTNS,'axis'), **args) + +def Categories(**args): + return Element(qname = (CHARTNS,'categories'), **args) + +def Chart(**args): + return Element(qname = (CHARTNS,'chart'), **args) + +def DataPoint(**args): + return Element(qname = (CHARTNS,'data-point'), **args) + +def Domain(**args): + return Element(qname = (CHARTNS,'domain'), **args) + +def ErrorIndicator(**args): + return Element(qname = (CHARTNS,'error-indicator'), **args) + +def Floor(**args): + return Element(qname = (CHARTNS,'floor'), **args) + +def Footer(**args): + return Element(qname = (CHARTNS,'footer'), **args) + +def Grid(**args): + return Element(qname = (CHARTNS,'grid'), **args) + +def Legend(**args): + return Element(qname = (CHARTNS,'legend'), **args) + +def MeanValue(**args): + return Element(qname = (CHARTNS,'mean-value'), **args) + +def PlotArea(**args): + return Element(qname = (CHARTNS,'plot-area'), **args) + +def RegressionCurve(**args): + return Element(qname = (CHARTNS,'regression-curve'), **args) + +def Series(**args): + return Element(qname = (CHARTNS,'series'), **args) + +def StockGainMarker(**args): + return Element(qname = (CHARTNS,'stock-gain-marker'), **args) + +def StockLossMarker(**args): + return Element(qname = (CHARTNS,'stock-loss-marker'), **args) + +def StockRangeLine(**args): + return Element(qname = (CHARTNS,'stock-range-line'), **args) + +def Subtitle(**args): + return Element(qname = (CHARTNS,'subtitle'), **args) + +def SymbolImage(**args): + return Element(qname = (CHARTNS,'symbol-image'), **args) + +def Title(**args): + return Element(qname = (CHARTNS,'title'), **args) + +def Wall(**args): + return Element(qname = (CHARTNS,'wall'), **args) + diff --git a/src/odf/config.py b/src/odf/config.py new file mode 100644 index 0000000000..f33f361396 --- /dev/null +++ b/src/odf/config.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import CONFIGNS +from element import Element + +# Autogenerated +def ConfigItem(**args): + return Element(qname = (CONFIGNS, 'config-item'), **args) + +def ConfigItemMapEntry(**args): + return Element(qname = (CONFIGNS,'config-item-map-entry'), **args) + +def ConfigItemMapIndexed(**args): + return Element(qname = (CONFIGNS,'config-item-map-indexed'), **args) + +def ConfigItemMapNamed(**args): + return Element(qname = (CONFIGNS,'config-item-map-named'), **args) + +def ConfigItemSet(**args): + return Element(qname = (CONFIGNS, 'config-item-set'), **args) + diff --git a/src/odf/dc.py b/src/odf/dc.py new file mode 100644 index 0000000000..7c967768bb --- /dev/null +++ b/src/odf/dc.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import DCNS +from element import Element + +# Autogenerated +def Creator(**args): + return Element(qname = (DCNS,'creator'), **args) + +def Date(**args): + return Element(qname = (DCNS,'date'), **args) + +def Description(**args): + return Element(qname = (DCNS,'description'), **args) + +def Language(**args): + return Element(qname = (DCNS,'language'), **args) + +def Subject(**args): + return Element(qname = (DCNS,'subject'), **args) + +def Title(**args): + return Element(qname = (DCNS,'title'), **args) + +# The following complete the Dublin Core elements, but there is no +# guarantee a compliant implementation of OpenDocument will preserve +# these elements + +#def Contributor(**args): +# return Element(qname = (DCNS,'contributor'), **args) + +#def Coverage(**args): +# return Element(qname = (DCNS,'coverage'), **args) + +#def Format(**args): +# return Element(qname = (DCNS,'format'), **args) + +#def Identifier(**args): +# return Element(qname = (DCNS,'identifier'), **args) + +#def Publisher(**args): +# return Element(qname = (DCNS,'publisher'), **args) + +#def Relation(**args): +# return Element(qname = (DCNS,'relation'), **args) + +#def Rights(**args): +# return Element(qname = (DCNS,'rights'), **args) + +#def Source(**args): +# return Element(qname = (DCNS,'source'), **args) + +#def Type(**args): +# return Element(qname = (DCNS,'type'), **args) diff --git a/src/odf/dr3d.py b/src/odf/dr3d.py new file mode 100644 index 0000000000..324ae1cf4f --- /dev/null +++ b/src/odf/dr3d.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import DR3DNS +from element import Element +from draw import StyleRefElement + +# Autogenerated +def Cube(**args): + return StyleRefElement(qname = (DR3DNS,'cube'), **args) + +def Extrude(**args): + return StyleRefElement(qname = (DR3DNS,'extrude'), **args) + +def Light(Element): + return StyleRefElement(qname = (DR3DNS,'light'), **args) + +def Rotate(**args): + return StyleRefElement(qname = (DR3DNS,'rotate'), **args) + +def Scene(**args): + return StyleRefElement(qname = (DR3DNS,'scene'), **args) + +def Sphere(**args): + return StyleRefElement(qname = (DR3DNS,'sphere'), **args) + diff --git a/src/odf/draw.py b/src/odf/draw.py new file mode 100644 index 0000000000..7692e5aa84 --- /dev/null +++ b/src/odf/draw.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import DRAWNS, STYLENS, PRESENTATIONNS +from element import Element + +def StyleRefElement(stylename=None, classnames=None, **args): + qattrs = {} + if stylename is not None: + f = stylename.getAttrNS(STYLENS, 'family') + if f == 'graphic': + qattrs[(DRAWNS,u'style-name')]= stylename + elif f == 'presentation': + qattrs[(PRESENTATIONNS,u'style-name')]= stylename + else: + raise ValueError, "Style's family must be either 'graphic' or 'presentation'" + if classnames is not None: + f = classnames[0].getAttrNS(STYLENS, 'family') + if f == 'graphic': + qattrs[(DRAWNS,u'class-names')]= classnames + elif f == 'presentation': + qattrs[(PRESENTATIONNS,u'class-names')]= classnames + else: + raise ValueError, "Style's family must be either 'graphic' or 'presentation'" + return Element(qattributes=qattrs, **args) + +def DrawElement(name=None, **args): + e = Element(name=name, **args) + if not args.has_key('displayname'): + e.setAttrNS(DRAWNS,'display-name', name) + return e + +# Autogenerated +def A(**args): + return Element(qname = (DRAWNS,'a'), **args) + +def Applet(**args): + return Element(qname = (DRAWNS,'applet'), **args) + +def AreaCircle(**args): + return Element(qname = (DRAWNS,'area-circle'), **args) + +def AreaPolygon(**args): + return Element(qname = (DRAWNS,'area-polygon'), **args) + +def AreaRectangle(**args): + return Element(qname = (DRAWNS,'area-rectangle'), **args) + +def Caption(**args): + return StyleRefElement(qname = (DRAWNS,'caption'), **args) + +def Circle(**args): + return StyleRefElement(qname = (DRAWNS,'circle'), **args) + +def Connector(**args): + return StyleRefElement(qname = (DRAWNS,'connector'), **args) + +def ContourPath(**args): + return Element(qname = (DRAWNS,'contour-path'), **args) + +def ContourPolygon(**args): + return Element(qname = (DRAWNS,'contour-polygon'), **args) + +def Control(**args): + return StyleRefElement(qname = (DRAWNS,'control'), **args) + +def CustomShape(**args): + return StyleRefElement(qname = (DRAWNS,'custom-shape'), **args) + +def Ellipse(**args): + return StyleRefElement(qname = (DRAWNS,'ellipse'), **args) + +def EnhancedGeometry(**args): + return Element(qname = (DRAWNS,'enhanced-geometry'), **args) + +def Equation(**args): + return Element(qname = (DRAWNS,'equation'), **args) + +def FillImage(**args): + return DrawElement(qname = (DRAWNS,'fill-image'), **args) + +def FloatingFrame(**args): + return Element(qname = (DRAWNS,'floating-frame'), **args) + +def Frame(**args): + return StyleRefElement(qname = (DRAWNS,'frame'), **args) + +def G(**args): + return StyleRefElement(qname = (DRAWNS,'g'), **args) + +def GluePoint(**args): + return Element(qname = (DRAWNS,'glue-point'), **args) + +def Gradient(**args): + return DrawElement(qname = (DRAWNS,'gradient'), **args) + +def Handle(**args): + return Element(qname = (DRAWNS,'handle'), **args) + +def Hatch(**args): + return DrawElement(qname = (DRAWNS,'hatch'), **args) + +def Image(**args): + return Element(qname = (DRAWNS,'image'), **args) + +def ImageMap(**args): + return Element(qname = (DRAWNS,'image-map'), **args) + +def Layer(**args): + return Element(qname = (DRAWNS,'layer'), **args) + +def LayerSet(**args): + return Element(qname = (DRAWNS,'layer-set'), **args) + +def Line(**args): + return StyleRefElement(qname = (DRAWNS,'line'), **args) + +def Marker(**args): + return DrawElement(qname = (DRAWNS,'marker'), **args) + +def Measure(**args): + return StyleRefElement(qname = (DRAWNS,'measure'), **args) + +def Object(**args): + return Element(qname = (DRAWNS,'object'), **args) + +def ObjectOle(**args): + return Element(qname = (DRAWNS,'object-ole'), **args) + +def Opacity(**args): + return DrawElement(qname = (DRAWNS,'opacity'), **args) + +def Page(**args): + return Element(qname = (DRAWNS,'page'), **args) + +def PageThumbnail(**args): + return StyleRefElement(qname = (DRAWNS,'page-thumbnail'), **args) + +def Param(**args): + return Element(qname = (DRAWNS,'param'), **args) + +def Path(**args): + return StyleRefElement(qname = (DRAWNS,'path'), **args) + +def Plugin(**args): + return Element(qname = (DRAWNS,'plugin'), **args) + +def Polygon(**args): + return StyleRefElement(qname = (DRAWNS,'polygon'), **args) + +def Polyline(**args): + return StyleRefElement(qname = (DRAWNS,'polyline'), **args) + +def Rect(**args): + return StyleRefElement(qname = (DRAWNS,'rect'), **args) + +def RegularPolygon(**args): + return StyleRefElement(qname = (DRAWNS,'regular-polygon'), **args) + +def StrokeDash(**args): + return DrawElement(qname = (DRAWNS,'stroke-dash'), **args) + +def TextBox(**args): + return Element(qname = (DRAWNS,'text-box'), **args) + diff --git a/src/odf/easyliststyle.py b/src/odf/easyliststyle.py new file mode 100644 index 0000000000..b2a54c210b --- /dev/null +++ b/src/odf/easyliststyle.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# Create a <text:list-style> element from a text string. +# Copyright (C) 2008 J. David Eisenberg +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contributor(s): +# + +import re +from style import Style, TextProperties, ListLevelProperties +from text import ListStyle,ListLevelStyleNumber,ListLevelStyleBullet + +""" +Create a <text:list-style> element from a string or array. + +List styles require a lot of code to create one level at a time. +These routines take a string and delimiter, or a list of +strings, and creates a <text:list-style> element for you. +Each item in the string (or array) represents a list level + * style for levels 1-10.</p> + * + * <p>If an item contains <code>1</code>, <code>I</code>, + * <code>i</code>, <code>A</code>, or <code>a</code>, then it is presumed + * to be a numbering style; otherwise it is a bulleted style.</p> +""" + +_MAX_LIST_LEVEL = 10 +SHOW_ALL_LEVELS = True +SHOW_ONE_LEVEL = False + +def styleFromString(name, specifiers, delim, spacing, showAllLevels): + specArray = specifiers.split(delim) + return styleFromList( name, specArray, spacing, showAllLevels ) + +def styleFromList( styleName, specArray, spacing, showAllLevels): + bullet = "" + numPrefix = "" + numSuffix = "" + numberFormat = "" + cssLengthNum = 0 + cssLengthUnits = "" + numbered = False + displayLevels = 0 + listStyle = ListStyle(name=styleName) + numFormatPattern = re.compile("([1IiAa])") + cssLengthPattern = re.compile("([^a-z]+)\\s*([a-z]+)?") + m = cssLengthPattern.search( spacing ) + if (m != None): + cssLengthNum = float(m.group(1)) + if (m.lastindex == 2): + cssLengthUnits = m.group(2) + i = 0 + while i < len(specArray): + specification = specArray[i] + m = numFormatPattern.search(specification) + if (m != None): + numberFormat = m.group(1) + numPrefix = specification[0:m.start(1)] + numSuffix = specification[m.end(1):] + bullet = "" + numbered = True + if (showAllLevels): + displayLevels = i + 1 + else: + displayLevels = 1 + else: # it's a bullet style + bullet = specification + numPrefix = "" + numSuffix = "" + numberFormat = "" + displayLevels = 1 + numbered = False + if (numbered): + lls = ListLevelStyleNumber(level=(i+1)) + if (numPrefix != ''): + lls.setAttribute('numprefix', numPrefix) + if (numSuffix != ''): + lls.setAttribute('numsuffix', numSuffix) + lls.setAttribute('displaylevels', displayLevels) + else: + lls = ListLevelStyleBullet(level=(i+1),bulletchar=bullet[0]) + llp = ListLevelProperties() + llp.setAttribute('spacebefore', str(cssLengthNum * (i+1)) + cssLengthUnits) + llp.setAttribute('minlabelwidth', str(cssLengthNum) + cssLengthUnits) + lls.addElement( llp ) + listStyle.addElement(lls) + i += 1 + return listStyle + +# vim: set expandtab sw=4 : diff --git a/src/odf/element.py b/src/odf/element.py new file mode 100644 index 0000000000..e6b3637bec --- /dev/null +++ b/src/odf/element.py @@ -0,0 +1,454 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +# Note: This script has copied a lot of text from xml.dom.minidom. +# Whatever license applies to that file also applies to this file. +# +import xml.dom +from xml.dom.minicompat import * +from namespaces import nsdict +import grammar +from attrconverters import AttrConverters + +# The following code is pasted form xml.sax.saxutils +# Tt makes it possible to run the code without the xml sax package installed +# To make it possible to have <rubbish> in your text elements, it is necessary to escape the texts +def _escape(data, entities={}): + """ Escape &, <, and > in a string of data. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + for chars, entity in entities.items(): + data = data.replace(chars, entity) + return data + +def _quoteattr(data, entities={}): + """ Escape and quote an attribute value. + + Escape &, <, and > in a string of data, then quote it for use as + an attribute value. The \" character will be escaped as well, if + necessary. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = _escape(data, entities) + if '"' in data: + if "'" in data: + data = '"%s"' % data.replace('"', """) + else: + data = "'%s'" % data + else: + data = '"%s"' % data + return data + +def _nssplit(qualifiedName): + """ Split a qualified name into namespace part and local part. """ + fields = qualifiedName.split(':', 1) + if len(fields) == 2: + return fields + else: + return (None, fields[0]) + +def _nsassign(namespace): + return nsdict.setdefault(namespace,"ns" + str(len(nsdict))) + +# Exceptions +class IllegalChild(StandardError): + """ Complains if you add an element to a parent where it is not allowed """ +class IllegalText(StandardError): + """ Complains if you add text or cdata to an element where it is not allowed """ + +class Node(xml.dom.Node): + """ super class for more specific nodes """ + parentNode = None + nextSibling = None + previousSibling = None + + def hasChildNodes(self): + """ Tells whether this element has any children; text nodes, + subelements, whatever. + """ + if self.childNodes: + return True + else: + return False + + def _get_childNodes(self): + return self.childNodes + + def _get_firstChild(self): + if self.childNodes: + return self.childNodes[0] + + def _get_lastChild(self): + if self.childNodes: + return self.childNodes[-1] + + def insertBefore(self, newChild, refChild): + if newChild.nodeType not in self._child_node_types: + raise IllegalChild, "%s cannot be child of %s" % (newChild.tagName, self.tagName) + if newChild.parentNode is not None: + newChild.parentNode.removeChild(newChild) + if refChild is None: + self.appendChild(newChild) + else: + try: + index = self.childNodes.index(refChild) + except ValueError: + raise xml.dom.NotFoundErr() + self.childNodes.insert(index, newChild) + newChild.nextSibling = refChild + refChild.previousSibling = newChild + if index: + node = self.childNodes[index-1] + node.nextSibling = newChild + newChild.previousSibling = node + else: + newChild.previousSibling = None + newChild.parentNode = self + return newChild + + def appendChild(self, node): + if node.nodeType == self.DOCUMENT_FRAGMENT_NODE: + for c in tuple(node.childNodes): + self.appendChild(c) + ### The DOM does not clearly specify what to return in this case + return node + if node.nodeType not in self._child_node_types: + raise IllegalChild, "<%s> is not allowed in %s" % ( node.tagName, self.tagName) + if node.parentNode is not None: + node.parentNode.removeChild(node) + _append_child(self, node) + node.nextSibling = None + return node + + def removeChild(self, oldChild): + #FIXME: update ownerDocument.element_dict or find other solution + try: + self.childNodes.remove(oldChild) + except ValueError: + raise xml.dom.NotFoundErr() + if oldChild.nextSibling is not None: + oldChild.nextSibling.previousSibling = oldChild.previousSibling + if oldChild.previousSibling is not None: + oldChild.previousSibling.nextSibling = oldChild.nextSibling + oldChild.nextSibling = oldChild.previousSibling = None + if self.ownerDocument: + self.ownerDocument.clear_caches() + oldChild.parentNode = None + return oldChild + +defproperty(Node, "firstChild", doc="First child node, or None.") +defproperty(Node, "lastChild", doc="Last child node, or None.") + +def _append_child(self, node): + # fast path with less checks; usable by DOM builders if careful + childNodes = self.childNodes + if childNodes: + last = childNodes[-1] + node.__dict__["previousSibling"] = last + last.__dict__["nextSibling"] = node + childNodes.append(node) + node.__dict__["parentNode"] = self + +class Childless: + """Mixin that makes childless-ness easy to implement and avoids + the complexity of the Node methods that deal with children. + """ + + attributes = None + childNodes = EmptyNodeList() + firstChild = None + lastChild = None + + def _get_firstChild(self): + return None + + def _get_lastChild(self): + return None + + def appendChild(self, node): + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes cannot have children") + + def hasChildNodes(self): + return False + + def insertBefore(self, newChild, refChild): + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes do not have children") + + def removeChild(self, oldChild): + raise xml.dom.NotFoundErr( + self.tagName + " nodes do not have children") + + def replaceChild(self, newChild, oldChild): + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes do not have children") + +class Text(Childless, Node): + nodeType = Node.TEXT_NODE + tagName = "Text" + + def __init__(self, data): + self.data = data + + def __str__(self): + return self.data + + def toXml(self,level,f): + """ Write XML in UTF-8 """ + if self.data: + f.write(_escape(unicode(self.data).encode('utf-8'))) + +class CDATASection(Childless, Text): + nodeType = Node.CDATA_SECTION_NODE + + def toXml(self,level,f): + if self.data: + f.write('<![CDATA[%s]]>' % self.data) + +class Element(Node): + """ Creates a arbitrary element and is intended to be subclassed not used on its own. + This element is the base of every element it defines a class which resembles + a xml-element. The main advantage of this kind of implementation is that you don't + have to create a toXML method for every different object. Every element + consists of an attribute, optional subelements, optional text and optional cdata. + """ + + nodeType = Node.ELEMENT_NODE + namespaces = {} # Due to shallow copy this is a static variable + + _child_node_types = (Node.ELEMENT_NODE, + Node.PROCESSING_INSTRUCTION_NODE, + Node.COMMENT_NODE, + Node.TEXT_NODE, + Node.CDATA_SECTION_NODE, + Node.ENTITY_REFERENCE_NODE) + + def __init__(self, attributes=None, text=None, cdata=None, qname=None, qattributes=None, check_grammar=True, **args): + if qname is not None: + self.qname = qname + assert(hasattr(self, 'qname')) + self.ownerDocument = None + self.childNodes=[] + self.allowed_children = grammar.allowed_children.get(self.qname) + namespace = self.qname[0] + prefix = _nsassign(namespace) + if not self.namespaces.has_key(namespace): + self.namespaces[namespace] = prefix + self.tagName = prefix + ":" + self.qname[1] + if text is not None: + self.addText(text) + if cdata is not None: + self.addCDATA(cdata) + + allowed_attrs = self.allowed_attributes() + if allowed_attrs is not None: + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + self.attributes={} + # Load the attributes from the 'attributes' argument + if attributes: + for attr, value in attributes.items(): + self.setAttribute(attr, value) + # Load the qualified attributes + if qattributes: + for attr, value in qattributes.items(): + self.setAttrNS(attr[0], attr[1], value) + if allowed_attrs is not None: + # Load the attributes from the 'args' argument + for arg in args.keys(): + self.setAttribute(arg, args[arg]) + else: + for arg in args.keys(): # If any attribute is allowed + self.attributes[arg]=args[arg] + if not check_grammar: + return + # Test that all mandatory attributes have been added. + required = grammar.required_attributes.get(self.qname) + if required: + for r in required: + if self.getAttrNS(r[0],r[1]) is None: + raise AttributeError, "Required attribute missing: %s in <%s>" % (r[1].lower().replace('-',''), self.tagName) + + def allowed_attributes(self): + return grammar.allowed_attributes.get(self.qname) + + def _setOwnerDoc(self, element): + element.ownerDocument = self.ownerDocument + for child in element.childNodes: + self._setOwnerDoc(child) + + def addElement(self, element, check_grammar=True): + """ adds an element to an Element + + Element.addElement(Element) + """ + if check_grammar and self.allowed_children is not None: + if element.qname not in self.allowed_children: + raise IllegalChild, "<%s> is not allowed in <%s>" % ( element.tagName, self.tagName) + self.appendChild(element) + self._setOwnerDoc(element) + if self.ownerDocument: + self.ownerDocument.rebuild_caches(element) + + def addText(self, text, check_grammar=True): + if check_grammar and self.qname not in grammar.allows_text: + raise IllegalText, "The <%s> element does not allow text" % self.tagName + else: + if text != '': + self.appendChild(Text(text)) + + def addCDATA(self, cdata, check_grammar=True): + if check_grammar and self.qname not in grammar.allows_text: + raise IllegalText, "The <%s> element does not allow text" % self.tagName + else: + self.appendChild(CDATASection(cdata)) + + def removeAttribute(self, attr, check_grammar=True): + """ Removes an attribute by name. """ + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + self.removeAttrNS(prefix, localname) + else: + raise AttributeError, "Unable to add simple attribute - use (namespace, localpart)" + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + if check_grammar and attr not in allowed_args: + raise AttributeError, "Attribute %s is not allowed in <%s>" % ( attr, self.tagName) + i = allowed_args.index(attr) + self.removeAttrNS(allowed_attrs[i][0], allowed_attrs[i][1]) + + def setAttribute(self, attr, value, check_grammar=True): + """ Add an attribute to the element + This is sort of a convenience method. All attributes in ODF have + namespaces. The library knows what attributes are legal and then allows + the user to provide the attribute as a keyword argument and the + library will add the correct namespace. + Must overwrite, If attribute already exists. + """ + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + self.setAttrNS(prefix, localname, value) + else: + raise AttributeError, "Unable to add simple attribute - use (namespace, localpart)" + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + if check_grammar and attr not in allowed_args: + raise AttributeError, "Attribute %s is not allowed in <%s>" % ( attr, self.tagName) + i = allowed_args.index(attr) + self.setAttrNS(allowed_attrs[i][0], allowed_attrs[i][1], value) + + def setAttrNS(self, namespace, localpart, value): + """ Add an attribute to the element + In case you need to add an attribute the library doesn't know about + then you must provide the full qualified name + It will not check that the attribute is legal according to the schema. + Must overwrite, If attribute already exists. + """ + allowed_attrs = self.allowed_attributes() + prefix = _nsassign(namespace) + if not self.namespaces.has_key(namespace): + self.namespaces[namespace] = prefix +# if allowed_attrs and (namespace, localpart) not in allowed_attrs: +# raise AttributeError, "Attribute %s:%s is not allowed in element <%s>" % ( prefix, localpart, self.tagName) + c = AttrConverters() + self.attributes[prefix + ":" + localpart] = c.convert((namespace, localpart), value, self.qname) + + def getAttrNS(self, namespace, localpart): + prefix = _nsassign(namespace) + if not self.namespaces.has_key(namespace): + self.namespaces[namespace] = prefix + return self.attributes.get(prefix + ":" + localpart) + + def removeAttrNS(self, namespace, localpart): + prefix = _nsassign(namespace) + if not self.namespaces.has_key(namespace): + self.namespaces[namespace] = prefix + del self.attributes[prefix + ":" + localpart] + + def getAttribute(self, attr): + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + return self.getAttrNS(prefix, localname) + else: + raise AttributeError, "Unable to get simple attribute - use (namespace, localpart)" + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + i = allowed_args.index(attr) + return self.getAttrNS(allowed_attrs[i][0], allowed_attrs[i][1]) + + def write_open_tag(self, level, f): + f.write('<'+self.tagName) + if level == 0: + for namespace, prefix in self.namespaces.items(): + f.write(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"') + for attkey in self.attributes.keys(): + f.write(' '+_escape(str(attkey))+'='+_quoteattr(unicode(self.attributes[attkey]).encode('utf-8'))) + f.write('>') + + def write_close_tag(self, level, f): + f.write('</'+self.tagName+'>') + + def toXml(self, level, f): + """ Generate XML stream out of the tree structure """ + f.write('<'+self.tagName) + if level == 0: + for namespace, prefix in self.namespaces.items(): + f.write(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"') + for attkey in self.attributes.keys(): + f.write(' '+_escape(str(attkey))+'='+_quoteattr(unicode(self.attributes[attkey]).encode('utf-8'))) + if self.childNodes: + f.write('>') + for element in self.childNodes: + element.toXml(level+1,f) + f.write('</'+self.tagName+'>') + else: + f.write('/>') + + def _getElementsByObj(self, obj, accumulator): + if self.qname == obj.qname: + accumulator.append(self) + for e in self.childNodes: + if e.nodeType == Node.ELEMENT_NODE: + accumulator = e._getElementsByObj(obj, accumulator) + return accumulator + + def getElementsByType(self, element): + obj = element(check_grammar=False) + return self._getElementsByObj(obj,[]) + diff --git a/src/odf/elementtypes.py b/src/odf/elementtypes.py new file mode 100644 index 0000000000..4663b1e81d --- /dev/null +++ b/src/odf/elementtypes.py @@ -0,0 +1,330 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import * + +# Inline element don't cause a box +# They are analogous to the HTML elements SPAN, B, I etc. +inline_elements = ( + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + + +struct_elements = ( + (CONFIGNS,'config-item-set'), + (TABLENS,u'table-cell'), +) + +# It is almost impossible to determine what elements are block elements. +# There are so many that don't fit the form +block_elements = ( + (TEXTNS,u'h'), + (TEXTNS,u'p'), + (TEXTNS,u'list'), + (TEXTNS,u'list-item'), + (TEXTNS,u'section'), +) + +declarative_elements = ( + (OFFICENS,u'font-face-decls'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (TABLENS,u'table-template'), + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'object-index-entry-template'), + (TEXTNS,u'object-index-source'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index-entry-template'), + (TEXTNS,u'table-index-source'), + (TEXTNS,u'table-of-content-entry-template'), + (TEXTNS,u'table-of-content-source'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index-entry-template'), + (TEXTNS,u'user-index-source'), + (TEXTNS,u'variable-decls'), +) + +empty_elements = ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'param'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (CHARTNS,u'categories'), + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'floor'), + (CHARTNS,u'grid'), + (CHARTNS,u'legend'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'symbol-image'), + (CHARTNS,u'wall'), + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'sphere'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'equation'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'gradient'), + (DRAWNS,u'handle'), + (DRAWNS,u'hatch'), + (DRAWNS,u'layer'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'param'), + (DRAWNS,u'stroke-dash'), + (FORMNS,u'connection-resource'), + (FORMNS,u'list-value'), + (FORMNS,u'property'), + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + (METANS,u'auto-reload'), + (METANS,u'document-statistic'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'template'), + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'boolean'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'fraction'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text-content'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (OFFICENS,u'dde-source'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'sound'), + (SCRIPTNS,u'event-listener'), + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + (STYLENS,u'drop-cap'), + (STYLENS,u'footnote-sep'), + (STYLENS,u'list-level-properties'), + (STYLENS,u'map'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'tab-stop'), + (STYLENS,u'text-properties'), + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-format'), + (SVGNS,u'font-face-name'), + (SVGNS,u'stop'), + (TABLENS,u'body'), + (TABLENS,u'cell-address'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'change-deletion'), + (TABLENS,u'consolidation'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-group-member'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-member'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotal'), + (TABLENS,u'dependency'), + (TABLENS,u'error-macro'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'filter-condition'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'highlighted-range'), + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'iteration'), + (TABLENS,u'label-range'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'movement-cut-off'), + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + (TABLENS,u'null-date'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + (TABLENS,u'operation'), + (TABLENS,u'scenario'), + (TABLENS,u'sort-by'), + (TABLENS,u'sort-groups'), + (TABLENS,u'source-range-address'), + (TABLENS,u'source-service'), + (TABLENS,u'subtotal-field'), + (TABLENS,u'table-column'), + (TABLENS,u'table-source'), + (TABLENS,u'target-range-address'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decl'), + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + (TEXTNS,u'index-source-style'), + (TEXTNS,u'line-break'), + (TEXTNS,u'page'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u's'), + (TEXTNS,u'section-source'), + (TEXTNS,u'sequence-decl'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'sort-key'), + (TEXTNS,u'tab'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-field-decl'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-decl') +) diff --git a/src/odf/form.py b/src/odf/form.py new file mode 100644 index 0000000000..7969b84018 --- /dev/null +++ b/src/odf/form.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import FORMNS +from element import Element + + +# Autogenerated +def Button(**args): + return Element(qname = (FORMNS,'button'), **args) + +def Checkbox(**args): + return Element(qname = (FORMNS,'checkbox'), **args) + +def Column(**args): + return Element(qname = (FORMNS,'column'), **args) + +def Combobox(**args): + return Element(qname = (FORMNS,'combobox'), **args) + +def ConnectionResource(**args): + return Element(qname = (FORMNS,'connection-resource'), **args) + +def Date(**args): + return Element(qname = (FORMNS,'date'), **args) + +def File(**args): + return Element(qname = (FORMNS,'file'), **args) + +def FixedText(**args): + return Element(qname = (FORMNS,'fixed-text'), **args) + +def Form(**args): + return Element(qname = (FORMNS,'form'), **args) + +def FormattedText(**args): + return Element(qname = (FORMNS,'formatted-text'), **args) + +def Frame(**args): + return Element(qname = (FORMNS,'frame'), **args) + +def GenericControl(**args): + return Element(qname = (FORMNS,'generic-control'), **args) + +def Grid(**args): + return Element(qname = (FORMNS,'grid'), **args) + +def Hidden(**args): + return Element(qname = (FORMNS,'hidden'), **args) + +def Image(**args): + return Element(qname = (FORMNS,'image'), **args) + +def ImageFrame(**args): + return Element(qname = (FORMNS,'image-frame'), **args) + +def Item(**args): + return Element(qname = (FORMNS,'item'), **args) + +def ListProperty(**args): + return Element(qname = (FORMNS,'list-property'), **args) + +def ListValue(**args): + return Element(qname = (FORMNS,'list-value'), **args) + +def Listbox(**args): + return Element(qname = (FORMNS,'listbox'), **args) + +def Number(**args): + return Element(qname = (FORMNS,'number'), **args) + +def Option(**args): + return Element(qname = (FORMNS,'option'), **args) + +def Password(**args): + return Element(qname = (FORMNS,'password'), **args) + +def Properties(**args): + return Element(qname = (FORMNS,'properties'), **args) + +def Property(**args): + return Element(qname = (FORMNS,'property'), **args) + +def Radio(**args): + return Element(qname = (FORMNS,'radio'), **args) + +def Text(**args): + return Element(qname = (FORMNS,'text'), **args) + +def Textarea(**args): + return Element(qname = (FORMNS,'textarea'), **args) + +def Time(**args): + return Element(qname = (FORMNS,'time'), **args) + +def ValueRange(**args): + return Element(qname = (FORMNS,'value-range'), **args) + diff --git a/src/odf/grammar.py b/src/odf/grammar.py new file mode 100644 index 0000000000..1c74463bea --- /dev/null +++ b/src/odf/grammar.py @@ -0,0 +1,8150 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +__doc__=""" In principle the OpenDocument schema converted to python structures. +Currently it contains the legal child elements of a given element. +To be used for validation check in the API +""" + +from namespaces import * + +# The following code is generated from the RelaxNG schema with this notice: + +# OASIS OpenDocument v1.0 +# OASIS standard, 1 May 2005 +# Relax-NG Manifest Schema + +# © 2002-2005 OASIS Open +# © 1999-2005 Sun Microsystems, Inc. + +# This document and translations of it may be copied and furnished +# to others, and derivative works that comment on or otherwise explain +# it or assist in its implementation may be prepared, copied, +# published and distributed, in whole or in part, without restriction +# of any kind, provided that the above copyright notice and this +# paragraph are included on all such copies and derivative works. +# However, this document itself does not be modified in any way, such +# as by removing the copyright notice or references to OASIS, except +# as needed for the purpose of developing OASIS specifications, in +# which case the procedures for copyrights defined in the OASIS +# Intellectual Property Rights document must be followed, or as +# required to translate it into languages other than English. +# + +allowed_children = { + (DCNS,u'creator') : ( + ), + (DCNS,u'date') : ( + ), + (DCNS,u'description') : ( + ), + (DCNS,u'language') : ( + ), + (DCNS,u'subject') : ( + ), + (DCNS,u'title') : ( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math') : None, + + (XFORMSNS,u'model') : None, + + (ANIMNS,u'animate') : ( + ), + (ANIMNS,u'animateColor') : ( + ), + (ANIMNS,u'animateMotion') : ( + ), + (ANIMNS,u'animateTransform') : ( + ), + (ANIMNS,u'audio') : ( + ), + (ANIMNS,u'command') : ( + (ANIMNS,u'param'), + ), +# allowed_children + (ANIMNS,u'iterate') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'par') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), +# allowed_children + (ANIMNS,u'param') : ( + ), + (ANIMNS,u'seq') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'set') : ( + ), + (ANIMNS,u'transitionFilter') : ( + ), + (CHARTNS,u'axis') : ( + (CHARTNS,u'categories'), + (CHARTNS,u'grid'), + (CHARTNS,u'title'), + ), +# allowed_children + (CHARTNS,u'categories') : ( + ), + (CHARTNS,u'chart') : ( + (CHARTNS,u'footer'), + (CHARTNS,u'legend'), + (CHARTNS,u'plot-area'), + (CHARTNS,u'subtitle'), + (CHARTNS,u'title'), + (TABLENS,u'table'), + ), + (CHARTNS,u'data-point') : ( + ), + (CHARTNS,u'domain') : ( + ), + (CHARTNS,u'error-indicator') : ( + ), + (CHARTNS,u'floor') : ( + ), + (CHARTNS,u'footer') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'grid') : ( + ), + (CHARTNS,u'legend') : ( + ), +# allowed_children + (CHARTNS,u'mean-value') : ( + ), + (CHARTNS,u'plot-area') : ( + (CHARTNS,u'axis'), + (CHARTNS,u'floor'), + (CHARTNS,u'series'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'wall'), + (DR3DNS,u'light'), + ), + (CHARTNS,u'regression-curve') : ( + ), + (CHARTNS,u'series') : ( + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + ), + (CHARTNS,u'stock-gain-marker') : ( + ), + (CHARTNS,u'stock-loss-marker') : ( + ), +# allowed_children + (CHARTNS,u'stock-range-line') : ( + ), + (CHARTNS,u'subtitle') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'symbol-image') : ( + ), + (CHARTNS,u'title') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'wall') : ( + ), + (CONFIGNS,u'config-item') : ( + ), + (CONFIGNS,u'config-item-map-entry') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (CONFIGNS,u'config-item-map-indexed') : ( + (CONFIGNS,u'config-item-map-entry'), + ), + (CONFIGNS,u'config-item-map-named') : ( + (CONFIGNS,u'config-item-map-entry'), + ), +# allowed_children + (CONFIGNS,u'config-item-set') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (MANIFESTNS,u'algorithm') : ( + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'encryption-data'), + ), + (MANIFESTNS,u'key-derivation') : ( + ), + (MANIFESTNS,u'manifest') : ( + (MANIFESTNS,u'file-entry'), + ), + (NUMBERNS,u'am-pm') : ( + ), + (NUMBERNS,u'boolean') : ( + ), +# allowed_children + (NUMBERNS,u'boolean-style') : ( + (NUMBERNS,u'boolean'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-style') : ( + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-symbol') : ( + ), + (NUMBERNS,u'date-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'day') : ( + ), + (NUMBERNS,u'day-of-week') : ( + ), + (NUMBERNS,u'embedded-text') : ( + ), + (NUMBERNS,u'era') : ( + ), + (NUMBERNS,u'fraction') : ( + ), + (NUMBERNS,u'hours') : ( + ), + (NUMBERNS,u'minutes') : ( + ), + (NUMBERNS,u'month') : ( + ), + (NUMBERNS,u'number') : ( + (NUMBERNS,u'embedded-text'), + ), + (NUMBERNS,u'number-style') : ( + (NUMBERNS,u'fraction'), + (NUMBERNS,u'number'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'percentage-style') : ( + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'quarter') : ( + ), + (NUMBERNS,u'scientific-number') : ( + ), + (NUMBERNS,u'seconds') : ( + ), + (NUMBERNS,u'text') : ( + ), + (NUMBERNS,u'text-content') : ( + ), + (NUMBERNS,u'text-style') : ( + (NUMBERNS,u'text'), + (NUMBERNS,u'text-content'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'time-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'week-of-year') : ( + ), + (NUMBERNS,u'year') : ( + ), + (DR3DNS,u'cube') : ( + ), + (DR3DNS,u'extrude') : ( + ), + (DR3DNS,u'light') : ( + ), + (DR3DNS,u'rotate') : ( + ), + (DR3DNS,u'scene') : ( + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'scene'), + (DR3DNS,u'sphere'), + ), + (DR3DNS,u'sphere') : ( + ), + (DRAWNS,u'a') : ( + (DRAWNS,u'frame'), + ), +# allowed_children + (DRAWNS,u'applet') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'area-circle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'area-polygon') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'area-rectangle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'caption') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'circle') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'connector') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'contour-path') : ( + ), + (DRAWNS,u'contour-polygon') : ( + ), + (DRAWNS,u'control') : ( + (DRAWNS,u'glue-point'), + ), + (DRAWNS,u'custom-shape') : ( + (DRAWNS,u'enhanced-geometry'), + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'ellipse') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'enhanced-geometry') : ( + (DRAWNS,u'equation'), + (DRAWNS,u'handle'), + ), + (DRAWNS,u'equation') : ( + ), + (DRAWNS,u'fill-image') : ( + ), + (DRAWNS,u'floating-frame') : ( + ), + (DRAWNS,u'frame') : ( + (DRAWNS,u'applet'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'image'), + (DRAWNS,u'image-map'), + (DRAWNS,u'object'), + (DRAWNS,u'object-ole'), + (DRAWNS,u'plugin'), + (DRAWNS,u'text-box'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'g') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'event-listeners'), + ), + (DRAWNS,u'glue-point') : ( + ), + (DRAWNS,u'gradient') : ( + ), + (DRAWNS,u'handle') : ( + ), + (DRAWNS,u'hatch') : ( + ), +# allowed_children + (DRAWNS,u'image') : ( + (OFFICENS,u'binary-data'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'image-map') : ( + (DRAWNS,u'area-circle'), + (DRAWNS,u'area-polygon'), + (DRAWNS,u'area-rectangle'), + ), + (DRAWNS,u'layer') : ( + ), + (DRAWNS,u'layer-set') : ( + (DRAWNS,u'layer'), + ), + (DRAWNS,u'line') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'marker') : ( + ), + (DRAWNS,u'measure') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'object') : ( + (MATHNS,u'math'), + (OFFICENS,u'document'), + ), + (DRAWNS,u'object-ole') : ( + (OFFICENS,u'binary-data'), + ), + (DRAWNS,u'opacity') : ( + ), + (DRAWNS,u'page') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'notes'), + ), + (DRAWNS,u'page-thumbnail') : ( + ), + (DRAWNS,u'param') : ( + ), + (DRAWNS,u'path') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'plugin') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'polyline') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'rect') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'regular-polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'stroke-dash') : ( + ), + (DRAWNS,u'text-box') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (FORMNS,u'button') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'checkbox') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'column') : ( + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'date'), + (FORMNS,u'formatted-text'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + ), + (FORMNS,u'combobox') : ( + (FORMNS,u'item'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'connection-resource') : ( + ), + (FORMNS,u'date') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'file') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'fixed-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'form') : ( + (FORMNS,u'button'), + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'connection-resource'), + (FORMNS,u'date'), + (FORMNS,u'file'), + (FORMNS,u'fixed-text'), + (FORMNS,u'form'), + (FORMNS,u'formatted-text'), + (FORMNS,u'frame'), + (FORMNS,u'generic-control'), + (FORMNS,u'grid'), + (FORMNS,u'hidden'), + (FORMNS,u'image'), + (FORMNS,u'image-frame'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'password'), + (FORMNS,u'properties'), + (FORMNS,u'radio'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + (FORMNS,u'time'), + (FORMNS,u'value-range'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'formatted-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'generic-control') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'grid') : ( + (FORMNS,u'column'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'hidden') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'image') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'image-frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'item') : ( + ), + (FORMNS,u'list-property') : ( + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + ), + (FORMNS,u'list-value') : ( + ), + (FORMNS,u'listbox') : ( + (FORMNS,u'option'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'number') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'option') : ( + ), + (FORMNS,u'password') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'properties') : ( + (FORMNS,u'list-property'), + (FORMNS,u'property'), + ), + (FORMNS,u'property') : ( + ), + (FORMNS,u'radio') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'textarea') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'p'), + ), + (FORMNS,u'time') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'value-range') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (METANS,u'auto-reload') : ( + ), + (METANS,u'creation-date') : ( + ), + (METANS,u'date-string') : ( + ), + (METANS,u'document-statistic') : ( + ), + (METANS,u'editing-cycles') : ( + ), + (METANS,u'editing-duration') : ( + ), + (METANS,u'generator') : ( + ), + (METANS,u'hyperlink-behaviour') : ( + ), + (METANS,u'initial-creator') : ( + ), + (METANS,u'keyword') : ( + ), + (METANS,u'print-date') : ( + ), + (METANS,u'printed-by') : ( + ), + (METANS,u'template') : ( + ), + (METANS,u'user-defined') : ( + ), +# allowed_children + (OFFICENS,u'annotation') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (METANS,u'date-string'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (OFFICENS,u'automatic-styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (STYLENS,u'page-layout'), + (STYLENS,u'style'), + (TEXTNS,u'list-style'), + ), + (OFFICENS,u'binary-data') : ( + ), + (OFFICENS,u'body') : ( + (OFFICENS,u'chart'), + (OFFICENS,u'drawing'), + (OFFICENS,u'image'), + (OFFICENS,u'presentation'), + (OFFICENS,u'spreadsheet'), + (OFFICENS,u'text'), + ), + (OFFICENS,u'change-info') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (TEXTNS,u'p'), + ), + (OFFICENS,u'chart') : ( + (CHARTNS,u'chart'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'dde-source') : ( + ), + (OFFICENS,u'document') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'meta'), + (OFFICENS,u'scripts'), + (OFFICENS,u'settings'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'document-content') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'scripts'), + ), + (OFFICENS,u'document-meta') : ( + (OFFICENS,u'meta'), + ), + (OFFICENS,u'document-settings') : ( + (OFFICENS,u'settings'), + ), + (OFFICENS,u'document-styles') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'drawing') : ( + (DRAWNS,u'page'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'event-listeners') : ( + (PRESENTATIONNS,u'event-listener'), + (SCRIPTNS,u'event-listener'), + ), + (OFFICENS,u'font-face-decls') : ( + (STYLENS,u'font-face'), + ), +# allowed_children + (OFFICENS,u'forms') : ( + (XFORMSNS,u'model'), + (FORMNS,u'form'), + ), + (OFFICENS,u'image') : ( + (DRAWNS,u'frame'), + ), + (OFFICENS,u'master-styles') : ( + (DRAWNS,u'layer-set'), + (STYLENS,u'handout-master'), + (STYLENS,u'master-page'), + (TABLENS,u'table-template'), + ), + (OFFICENS,u'meta') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (METANS,u'auto-reload'), + (METANS,u'creation-date'), + (METANS,u'document-statistic'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), + (METANS,u'generator'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'template'), + (METANS,u'user-defined'), + ), + (OFFICENS,u'presentation') : ( + (DRAWNS,u'page'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (PRESENTATIONNS,u'settings'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (OFFICENS,u'script') : None, + + (OFFICENS,u'scripts') : ( + (OFFICENS,u'event-listeners'), + (OFFICENS,u'script'), + ), + (OFFICENS,u'settings') : ( + (CONFIGNS,u'config-item-set'), + ), + (OFFICENS,u'spreadsheet') : ( + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TABLENS,u'tracked-changes'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'gradient'), + (DRAWNS,u'hatch'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'stroke-dash'), + (STYLENS,u'default-style'), + (STYLENS,u'presentation-page-layout'), + (STYLENS,u'style'), + (SVGNS,u'linearGradient'), + (SVGNS,u'radialGradient'), + (TEXTNS,u'bibliography-configuration'), + (TEXTNS,u'linenumbering-configuration'), + (TEXTNS,u'list-style'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'outline-style'), + ), + (OFFICENS,u'text') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'page-sequence'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (PRESENTATIONNS,u'animation-group') : ( + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'animations') : ( + (PRESENTATIONNS,u'animation-group'), + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'date-time') : ( + ), + (PRESENTATIONNS,u'date-time-decl') : ( + ), + (PRESENTATIONNS,u'dim') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'event-listener') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'footer') : ( + ), + (PRESENTATIONNS,u'footer-decl') : ( + ), + (PRESENTATIONNS,u'header') : ( + ), + (PRESENTATIONNS,u'header-decl') : ( + ), + (PRESENTATIONNS,u'hide-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'hide-text') : ( + (PRESENTATIONNS,u'sound'), + ), +# allowed_children + (PRESENTATIONNS,u'notes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), + (PRESENTATIONNS,u'placeholder') : ( + ), + (PRESENTATIONNS,u'play') : ( + ), + (PRESENTATIONNS,u'settings') : ( + (PRESENTATIONNS,u'show'), + ), + (PRESENTATIONNS,u'show') : ( + ), + (PRESENTATIONNS,u'show-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'show-text') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'sound') : ( + ), + (SCRIPTNS,u'event-listener') : ( + ), + (STYLENS,u'background-image') : ( + (OFFICENS,u'binary-data'), + ), + (STYLENS,u'chart-properties') : ( + (CHARTNS,u'symbol-image'), + ), + (STYLENS,u'column') : ( + ), + (STYLENS,u'column-sep') : ( + ), + (STYLENS,u'columns') : ( + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + ), + (STYLENS,u'default-style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'drawing-page-properties') : ( + (PRESENTATIONNS,u'sound'), + ), + (STYLENS,u'drop-cap') : ( + ), + (STYLENS,u'font-face') : ( + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-src'), + ), + (STYLENS,u'footer') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'footer-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'footer-style') : ( + (STYLENS,u'header-footer-properties'), + ), + (STYLENS,u'footnote-sep') : ( + ), + (STYLENS,u'graphic-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'list-style'), + ), + (STYLENS,u'handout-master') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), + (STYLENS,u'header') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (STYLENS,u'header-footer-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'header-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'header-style') : ( + (STYLENS,u'header-footer-properties'), + ), + (STYLENS,u'list-level-properties') : ( + ), + (STYLENS,u'map') : ( + ), + (STYLENS,u'master-page') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'notes'), + (STYLENS,u'footer'), + (STYLENS,u'footer-left'), + (STYLENS,u'header'), + (STYLENS,u'header-left'), + (STYLENS,u'style'), + ), + (STYLENS,u'page-layout') : ( + (STYLENS,u'footer-style'), + (STYLENS,u'header-style'), + (STYLENS,u'page-layout-properties'), + ), + (STYLENS,u'page-layout-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (STYLENS,u'footnote-sep'), + ), + (STYLENS,u'paragraph-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'drop-cap'), + (STYLENS,u'tab-stops'), + ), + (STYLENS,u'presentation-page-layout') : ( + (PRESENTATIONNS,u'placeholder'), + ), + (STYLENS,u'region-center') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-left') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-right') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'ruby-properties') : ( + ), + (STYLENS,u'section-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'notes-configuration'), + ), + (STYLENS,u'style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'map'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'tab-stop') : ( + ), + (STYLENS,u'tab-stops') : ( + (STYLENS,u'tab-stop'), + ), + (STYLENS,u'table-cell-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-column-properties') : ( + ), + (STYLENS,u'table-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-row-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'text-properties') : ( + ), + (SVGNS,u'definition-src') : ( + ), + (SVGNS,u'desc') : ( + ), + (SVGNS,u'font-face-format') : ( + ), + (SVGNS,u'font-face-name') : ( + ), + (SVGNS,u'font-face-src') : ( + (SVGNS,u'font-face-name'), + (SVGNS,u'font-face-uri'), + ), + (SVGNS,u'font-face-uri') : ( + (SVGNS,u'font-face-format'), + ), + (SVGNS,u'linearGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'radialGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'stop') : ( + ), + (TABLENS,u'body') : ( + ), + (TABLENS,u'calculation-settings') : ( + (TABLENS,u'iteration'), + (TABLENS,u'null-date'), + ), +# allowed_children + (TABLENS,u'cell-address') : ( + ), + (TABLENS,u'cell-content-change') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cell-address'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'previous'), + ), + (TABLENS,u'cell-content-deletion') : ( + (TABLENS,u'cell-address'), + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'cell-range-source') : ( + ), + (TABLENS,u'change-deletion') : ( + ), + (TABLENS,u'change-track-table-cell') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'consolidation') : ( + ), + (TABLENS,u'content-validation') : ( + (OFFICENS,u'event-listeners'), + (TABLENS,u'error-macro'), + (TABLENS,u'error-message'), + (TABLENS,u'help-message'), + ), + (TABLENS,u'content-validations') : ( + (TABLENS,u'content-validation'), + ), + (TABLENS,u'covered-table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TABLENS,u'cut-offs') : ( + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'movement-cut-off'), + ), + (TABLENS,u'data-pilot-display-info') : ( + ), + (TABLENS,u'data-pilot-field') : ( + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-groups'), + (TABLENS,u'data-pilot-level'), + ), + (TABLENS,u'data-pilot-field-reference') : ( + ), + (TABLENS,u'data-pilot-group') : ( + (TABLENS,u'data-pilot-group-member'), + ), + (TABLENS,u'data-pilot-group-member') : ( + ), + (TABLENS,u'data-pilot-groups') : ( + (TABLENS,u'data-pilot-group'), + ), + (TABLENS,u'data-pilot-layout-info') : ( + ), + (TABLENS,u'data-pilot-level') : ( + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-members'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotals'), + ), + (TABLENS,u'data-pilot-member') : ( + ), + (TABLENS,u'data-pilot-members') : ( + (TABLENS,u'data-pilot-member'), + ), + (TABLENS,u'data-pilot-sort-info') : ( + ), + (TABLENS,u'data-pilot-subtotal') : ( + ), + (TABLENS,u'data-pilot-subtotals') : ( + (TABLENS,u'data-pilot-subtotal'), + ), +# allowed_children + (TABLENS,u'data-pilot-table') : ( + (TABLENS,u'data-pilot-field'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'source-cell-range'), + (TABLENS,u'source-service'), + ), + (TABLENS,u'data-pilot-tables') : ( + (TABLENS,u'data-pilot-table'), + ), + (TABLENS,u'database-range') : ( + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'filter'), + (TABLENS,u'sort'), + (TABLENS,u'subtotal-rules'), + ), + (TABLENS,u'database-ranges') : ( + (TABLENS,u'database-range'), + ), + (TABLENS,u'database-source-query') : ( + ), + (TABLENS,u'database-source-sql') : ( + ), + (TABLENS,u'database-source-table') : ( + ), + (TABLENS,u'dde-link') : ( + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + ), + (TABLENS,u'dde-links') : ( + (TABLENS,u'dde-link'), + ), + (TABLENS,u'deletion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cut-offs'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'deletions') : ( + (TABLENS,u'cell-content-deletion'), + (TABLENS,u'change-deletion'), + ), + (TABLENS,u'dependencies') : ( + (TABLENS,u'dependency'), + ), + (TABLENS,u'dependency') : ( + ), + (TABLENS,u'detective') : ( + (TABLENS,u'highlighted-range'), + (TABLENS,u'operation'), + ), + (TABLENS,u'error-macro') : ( + ), + (TABLENS,u'error-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'even-columns') : ( + ), + (TABLENS,u'even-rows') : ( + ), + (TABLENS,u'filter') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-and') : ( + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-condition') : ( + ), + (TABLENS,u'filter-or') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + ), +# allowed_children + (TABLENS,u'first-column') : ( + ), + (TABLENS,u'first-row') : ( + ), + (TABLENS,u'help-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'highlighted-range') : ( + ), + (TABLENS,u'insertion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'insertion-cut-off') : ( + ), + (TABLENS,u'iteration') : ( + ), + (TABLENS,u'label-range') : ( + ), + (TABLENS,u'label-ranges') : ( + (TABLENS,u'label-range'), + ), + (TABLENS,u'last-column') : ( + ), + (TABLENS,u'last-row') : ( + ), + (TABLENS,u'movement') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'source-range-address'), + (TABLENS,u'target-range-address'), + ), + (TABLENS,u'movement-cut-off') : ( + ), + (TABLENS,u'named-expression') : ( + ), + (TABLENS,u'named-expressions') : ( + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + ), + (TABLENS,u'named-range') : ( + ), + (TABLENS,u'null-date') : ( + ), + (TABLENS,u'odd-columns') : ( + ), + (TABLENS,u'odd-rows') : ( + ), + (TABLENS,u'operation') : ( + ), + (TABLENS,u'previous') : ( + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'scenario') : ( + ), + (TABLENS,u'shapes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), + (TABLENS,u'sort') : ( + (TABLENS,u'sort-by'), + ), + (TABLENS,u'sort-by') : ( + ), + (TABLENS,u'sort-groups') : ( + ), + (TABLENS,u'source-cell-range') : ( + (TABLENS,u'filter'), + ), + (TABLENS,u'source-range-address') : ( + ), + (TABLENS,u'source-service') : ( + ), + (TABLENS,u'subtotal-field') : ( + ), + (TABLENS,u'subtotal-rule') : ( + (TABLENS,u'subtotal-field'), + ), + (TABLENS,u'subtotal-rules') : ( + (TABLENS,u'sort-groups'), + (TABLENS,u'subtotal-rule'), + ), +# allowed_children + (TABLENS,u'table') : ( + (OFFICENS,u'dde-source'), + (OFFICENS,u'forms'), + (TEXTNS,u'soft-page-break'), + (TABLENS,u'scenario'), + (TABLENS,u'shapes'), + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + (TABLENS,u'table-source'), + ), + (TABLENS,u'table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TABLENS,u'table-column') : ( + ), + (TABLENS,u'table-column-group') : ( + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + ), + (TABLENS,u'table-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-row') : ( + (TABLENS,u'covered-table-cell'), + (TABLENS,u'table-cell'), + ), + (TABLENS,u'table-row-group') : ( + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + ), + (TABLENS,u'table-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-source') : ( + ), + (TABLENS,u'table-template') : ( + (TABLENS,u'body'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + ), + (TABLENS,u'target-range-address') : ( + ), + (TABLENS,u'tracked-changes') : ( + (TABLENS,u'cell-content-change'), + (TABLENS,u'deletion'), + (TABLENS,u'insertion'), + (TABLENS,u'movement'), + ), +# allowed_children + (TEXTNS,u'a') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'event-listeners'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), + (TEXTNS,u'alphabetical-index') : ( + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file') : ( + ), + (TEXTNS,u'alphabetical-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'alphabetical-index-mark') : ( + ), + (TEXTNS,u'alphabetical-index-mark-end') : ( + ), + (TEXTNS,u'alphabetical-index-mark-start') : ( + ), + (TEXTNS,u'alphabetical-index-source') : ( + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'author-initials') : ( + ), + (TEXTNS,u'author-name') : ( + ), + (TEXTNS,u'bibliography') : ( + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'bibliography-configuration') : ( + (TEXTNS,u'sort-key'), + ), + (TEXTNS,u'bibliography-entry-template') : ( + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + ), +# allowed_children + (TEXTNS,u'bibliography-mark') : ( + ), + (TEXTNS,u'bibliography-source') : ( + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'bookmark') : ( + ), + (TEXTNS,u'bookmark-end') : ( + ), + (TEXTNS,u'bookmark-ref') : ( + ), + (TEXTNS,u'bookmark-start') : ( + ), + (TEXTNS,u'change') : ( + ), + (TEXTNS,u'change-end') : ( + ), + (TEXTNS,u'change-start') : ( + ), + (TEXTNS,u'changed-region') : ( + (TEXTNS,u'deletion'), + (TEXTNS,u'format-change'), + (TEXTNS,u'insertion'), + ), + (TEXTNS,u'chapter') : ( + ), + (TEXTNS,u'conditional-text') : ( + ), + (TEXTNS,u'creation-date') : ( + ), + (TEXTNS,u'creation-time') : ( + ), + (TEXTNS,u'creator') : ( + ), + (TEXTNS,u'database-display') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-name') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-next') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-number') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-select') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'date') : ( + ), + (TEXTNS,u'dde-connection') : ( + ), + (TEXTNS,u'dde-connection-decl') : ( + ), + (TEXTNS,u'dde-connection-decls') : ( + (TEXTNS,u'dde-connection-decl'), + ), +# allowed_children + (TEXTNS,u'deletion') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'change-info'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'description') : ( + ), + (TEXTNS,u'editing-cycles') : ( + ), + (TEXTNS,u'editing-duration') : ( + ), + (TEXTNS,u'execute-macro') : ( + (OFFICENS,u'event-listeners'), + ), + (TEXTNS,u'expression') : ( + ), + (TEXTNS,u'file-name') : ( + ), + (TEXTNS,u'format-change') : ( + (OFFICENS,u'change-info'), + ), +# allowed_children + (TEXTNS,u'h') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), + (TEXTNS,u'hidden-paragraph') : ( + ), + (TEXTNS,u'hidden-text') : ( + ), + (TEXTNS,u'illustration-index') : ( + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'illustration-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'illustration-index-source') : ( + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), +# allowed_children + (TEXTNS,u'index-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-entry-bibliography') : ( + ), + (TEXTNS,u'index-entry-chapter') : ( + ), + (TEXTNS,u'index-entry-link-end') : ( + ), + (TEXTNS,u'index-entry-link-start') : ( + ), + (TEXTNS,u'index-entry-page-number') : ( + ), + (TEXTNS,u'index-entry-span') : ( + ), + (TEXTNS,u'index-entry-tab-stop') : ( + ), + (TEXTNS,u'index-entry-text') : ( + ), + (TEXTNS,u'index-source-style') : ( + ), + (TEXTNS,u'index-source-styles') : ( + (TEXTNS,u'index-source-style'), + ), +# allowed_children + (TEXTNS,u'index-title') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-title-template') : ( + ), + (TEXTNS,u'initial-creator') : ( + ), + (TEXTNS,u'insertion') : ( + (OFFICENS,u'change-info'), + ), + (TEXTNS,u'keywords') : ( + ), + (TEXTNS,u'line-break') : ( + ), + (TEXTNS,u'linenumbering-configuration') : ( + (TEXTNS,u'linenumbering-separator'), + ), + (TEXTNS,u'linenumbering-separator') : ( + ), + (TEXTNS,u'list') : ( + (TEXTNS,u'list-header'), + (TEXTNS,u'list-item'), + ), + (TEXTNS,u'list-header') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + ), + (TEXTNS,u'list-item') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + (TEXTNS,u'soft-page-break'), + ), + (TEXTNS,u'list-level-style-bullet') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-level-style-image') : ( + (OFFICENS,u'binary-data'), + (STYLENS,u'list-level-properties'), + ), + (TEXTNS,u'list-level-style-number') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-style') : ( + (TEXTNS,u'list-level-style-bullet'), + (TEXTNS,u'list-level-style-image'), + (TEXTNS,u'list-level-style-number'), + ), + (TEXTNS,u'measure') : ( + ), + (TEXTNS,u'modification-date') : ( + ), + (TEXTNS,u'modification-time') : ( + ), + (TEXTNS,u'note') : ( + (TEXTNS,u'note-body'), + (TEXTNS,u'note-citation'), + ), +# allowed_children + (TEXTNS,u'note-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'note-citation') : ( + ), + (TEXTNS,u'note-continuation-notice-backward') : ( + ), + (TEXTNS,u'note-continuation-notice-forward') : ( + ), + (TEXTNS,u'note-ref') : ( + ), + (TEXTNS,u'notes-configuration') : ( + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + ), + (TEXTNS,u'number') : ( + ), + (TEXTNS,u'numbered-paragraph') : ( + (TEXTNS,u'h'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + ), + (TEXTNS,u'object-count') : ( + ), + (TEXTNS,u'object-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'object-index-source'), + ), + (TEXTNS,u'object-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'object-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'object-index-entry-template'), + ), + (TEXTNS,u'outline-level-style') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'outline-style') : ( + (TEXTNS,u'outline-level-style'), + ), +# allowed_children + (TEXTNS,u'p') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + ), + (TEXTNS,u'page') : ( + ), + (TEXTNS,u'page-continuation') : ( + ), + (TEXTNS,u'page-number') : ( + ), + (TEXTNS,u'page-sequence') : ( + (TEXTNS,u'page'), + ), + (TEXTNS,u'page-variable-get') : ( + ), + (TEXTNS,u'page-variable-set') : ( + ), + (TEXTNS,u'placeholder') : ( + ), + (TEXTNS,u'print-date') : ( + ), + (TEXTNS,u'print-time') : ( + ), + (TEXTNS,u'printed-by') : ( + ), + (TEXTNS,u'reference-mark') : ( + ), + (TEXTNS,u'reference-mark-end') : ( + ), + (TEXTNS,u'reference-mark-start') : ( + ), + (TEXTNS,u'ruby') : ( + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + ), + (TEXTNS,u'ruby-base') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), + (TEXTNS,u'ruby-text') : ( + ), + (TEXTNS,u's') : ( + ), + (TEXTNS,u'script') : ( + ), + (TEXTNS,u'section') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'section-source'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'section-source') : ( + ), + (TEXTNS,u'sender-city') : ( + ), + (TEXTNS,u'sender-company') : ( + ), + (TEXTNS,u'sender-country') : ( + ), + (TEXTNS,u'sender-email') : ( + ), + (TEXTNS,u'sender-fax') : ( + ), + (TEXTNS,u'sender-firstname') : ( + ), + (TEXTNS,u'sender-initials') : ( + ), + (TEXTNS,u'sender-lastname') : ( + ), + (TEXTNS,u'sender-phone-private') : ( + ), + (TEXTNS,u'sender-phone-work') : ( + ), + (TEXTNS,u'sender-position') : ( + ), + (TEXTNS,u'sender-postal-code') : ( + ), + (TEXTNS,u'sender-state-or-province') : ( + ), + (TEXTNS,u'sender-street') : ( + ), + (TEXTNS,u'sender-title') : ( + ), + (TEXTNS,u'sequence') : ( + ), + (TEXTNS,u'sequence-decl') : ( + ), + (TEXTNS,u'sequence-decls') : ( + (TEXTNS,u'sequence-decl'), + ), + (TEXTNS,u'sequence-ref') : ( + ), + (TEXTNS,u'sheet-name') : ( + ), + (TEXTNS,u'sort-key') : ( + ), + (TEXTNS,u'span') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), + (TEXTNS,u'subject') : ( + ), + (TEXTNS,u'tab') : ( + ), + (TEXTNS,u'table-formula') : ( + ), + (TEXTNS,u'table-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-index-source'), + ), + (TEXTNS,u'table-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-index-entry-template'), + ), + (TEXTNS,u'table-of-content') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-of-content-source'), + ), + (TEXTNS,u'table-of-content-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-of-content-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-of-content-entry-template'), + ), + (TEXTNS,u'template-name') : ( + ), + (TEXTNS,u'text-input') : ( + ), + (TEXTNS,u'time') : ( + ), + (TEXTNS,u'title') : ( + ), + (TEXTNS,u'toc-mark') : ( + ), + (TEXTNS,u'toc-mark-end') : ( + ), + (TEXTNS,u'toc-mark-start') : ( + ), +# allowed_children + (TEXTNS,u'tracked-changes') : ( + (TEXTNS,u'changed-region'), + ), + (TEXTNS,u'user-defined') : ( + ), + (TEXTNS,u'user-field-decl') : ( + ), + (TEXTNS,u'user-field-decls') : ( + (TEXTNS,u'user-field-decl'), + ), + (TEXTNS,u'user-field-get') : ( + ), + (TEXTNS,u'user-field-input') : ( + ), + (TEXTNS,u'user-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'user-index-source'), + ), + (TEXTNS,u'user-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), +# allowed_children + (TEXTNS,u'user-index-mark') : ( + ), + (TEXTNS,u'user-index-mark-end') : ( + ), + (TEXTNS,u'user-index-mark-start') : ( + ), + (TEXTNS,u'user-index-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'user-index-entry-template'), + ), + (TEXTNS,u'variable-decl') : ( + ), + (TEXTNS,u'variable-decls') : ( + (TEXTNS,u'variable-decl'), + ), + (TEXTNS,u'variable-get') : ( + ), + (TEXTNS,u'variable-input') : ( + ), + (TEXTNS,u'variable-set') : ( + ), +} + +struct_elements = ( # Unused? + (CONFIGNS,'config-item-set'), + (TABLENS,u'table-cell'), +) +# +# List of elements that allows text nodes +# +allows_text = ( + (CONFIGNS,u'config-item'), + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (FORMNS,u'item'), + (FORMNS,u'option'), + (MATHNS,u'math'), + (METANS,u'creation-date'), + (METANS,u'date-string'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), + (METANS,u'generator'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'user-defined'), + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'embedded-text'), + (NUMBERNS,u'text'), + (OFFICENS,u'binary-data'), + (OFFICENS,u'script'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (SVGNS,u'desc'), + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'h'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'linenumbering-separator'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-citation'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'object-count'), + (TEXTNS,u'p'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + +# Only the elements with at least one required attribute is listed + +required_attributes = { + (ANIMNS,u'animate'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateColor'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateMotion'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateTransform'): ( + (SVGNS,u'type'), + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'command'): ( + (ANIMNS,u'command'), + ), + (ANIMNS,u'param'): ( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'set'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'transitionFilter'): ( + (SMILNS,u'type'), + ), + (CHARTNS,u'axis'): ( + (CHARTNS,u'dimension'), + ), + (CHARTNS,u'chart'): ( + (CHARTNS,u'class'), + ), + (CHARTNS,u'symbol-image'): ( + (XLINKNS,u'href'), + ), + (CONFIGNS,u'config-item'): ( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'): ( + (CONFIGNS,u'name'), + ), + (NUMBERNS,u'boolean-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'currency-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'date-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'embedded-text'): ( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'number-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'percentage-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'text-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'time-style'): ( + (STYLENS,u'name'), + ), + (DR3DNS,u'extrude'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DR3DNS,u'light'): ( + (DR3DNS,u'direction'), + ), + (DR3DNS,u'rotate'): ( + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), + (DRAWNS,u'a'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'area-circle'): ( + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'r'), + ), + (DRAWNS,u'area-polygon'): ( + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'points'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'area-rectangle'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (SVGNS,u'width'), + ), + (DRAWNS,u'contour-path'): ( + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), + (DRAWNS,u'contour-polygon'): ( + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'control'): ( + (DRAWNS,u'control'), + ), + (DRAWNS,u'fill-image'): ( + (XLINKNS,u'href'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'floating-frame'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'glue-point'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'align'), + (DRAWNS,u'id'), + ), + (DRAWNS,u'gradient'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'handle'): ( + (DRAWNS,u'handle-position'), + ), + (DRAWNS,u'hatch'): ( + (DRAWNS,u'style'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'layer'): ( + (DRAWNS,u'name'), + ), + (DRAWNS,u'line'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'marker'): ( + (SVGNS,u'd'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'measure'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'opacity'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'page'): ( + (DRAWNS,u'master-page-name'), + ), + (DRAWNS,u'path'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'plugin'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'polygon'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'polyline'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'regular-polygon'): ( + (DRAWNS,u'corners'), + ), + (DRAWNS,u'stroke-dash'): ( + (DRAWNS,u'name'), + ), + (FORMNS,u'button'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'checkbox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'combobox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'connection-resource'): ( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'file'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'fixed-text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'formatted-text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'frame'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'generic-control'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'grid'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'hidden'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'image'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'image-frame'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'list-property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'list-value'): ( + (OFFICENS,u'string-value'), + ), + (FORMNS,u'listbox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'number'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'password'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'radio'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'textarea'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'time'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'value-range'): ( + (FORMNS,u'id'), + ), + (MANIFESTNS,u'algorithm') : ( + (MANIFESTNS,u'algorithm-name'), + (MANIFESTNS,u'initialisation-vector'), + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'checksum-type'), + (MANIFESTNS,u'checksum'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'full-path'), + (MANIFESTNS,u'media-type'), + ), + (MANIFESTNS,u'key-derivation') : ( + (MANIFESTNS,u'key-derivation-name'), + (MANIFESTNS,u'salt'), + (MANIFESTNS,u'iteration-count'), + ), +# required_attributes + (METANS,u'template'): ( + (XLINKNS,u'href'), + ), + (METANS,u'user-defined'): ( + (METANS,u'name'), + ), + (OFFICENS,u'dde-source'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'dde-item'), + ), + (OFFICENS,u'document'): ( + (OFFICENS,u'mimetype'), + ), + (OFFICENS,u'script'): ( + (SCRIPTNS,u'language'), + ), + (PRESENTATIONNS,u'date-time-decl'): ( + (PRESENTATIONNS,u'source'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'): ( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'event-listener'): ( + (PRESENTATIONNS,u'action'), + (SCRIPTNS,u'event-name'), + ), + (PRESENTATIONNS,u'footer-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'hide-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'placeholder'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show'): ( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'): ( + (XLINKNS,u'href'), + ), + (SCRIPTNS,u'event-listener'): ( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'event-name'), + ), + (STYLENS,u'column'): ( + (STYLENS,u'rel-width'), + ), + (STYLENS,u'column-sep'): ( + (STYLENS,u'width'), + ), + (STYLENS,u'columns'): ( + (FONS,u'column-count'), + ), + (STYLENS,u'font-face'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'handout-master'): ( + (STYLENS,u'page-layout-name'), + ), + (STYLENS,u'map'): ( + (STYLENS,u'apply-style-name'), + (STYLENS,u'condition'), + ), + (STYLENS,u'master-page'): ( + (STYLENS,u'page-layout-name'), + (STYLENS,u'name'), + ), + (STYLENS,u'page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'presentation-page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'style'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'tab-stop'): ( + (STYLENS,u'position'), + ), + (SVGNS,u'definition-src'): ( + (XLINKNS,u'href'), + ), + (SVGNS,u'font-face-uri'): ( + (XLINKNS,u'href'), + ), + (SVGNS,u'linearGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'radialGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'stop'): ( + (SVGNS,u'offset'), + ), + (TABLENS,u'body'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'cell-address'): ( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'): ( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (XLINKNS,u'href'), + (TABLENS,u'name'), + ), + (TABLENS,u'consolidation'): ( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + ), + (TABLENS,u'content-validation'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-display-info'): ( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), +# required_attributes + (TABLENS,u'data-pilot-field'): ( + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'): ( + (TABLENS,u'field-name'), + (TABLENS,u'type'), + ), + (TABLENS,u'data-pilot-group'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'): ( + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'): ( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-sort-info'): ( + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'): ( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-table'): ( + (TABLENS,u'target-range-address'), + (TABLENS,u'name'), + ), + (TABLENS,u'database-range'): ( + (TABLENS,u'target-range-address'), + ), + (TABLENS,u'database-source-query'): ( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'database-source-sql'): ( + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'): ( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'deletion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'dependency'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'even-columns'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'even-rows'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'filter-condition'): ( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'value'), + ), + (TABLENS,u'first-column'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'first-row'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'insertion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'): ( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), + (TABLENS,u'label-range'): ( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'last-column'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'last-row'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'movement'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'named-expression'): ( + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-range'): ( + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'odd-columns'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'odd-rows'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'operation'): ( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), + (TABLENS,u'scenario'): ( + (TABLENS,u'is-active'), + (TABLENS,u'scenario-ranges'), + ), + (TABLENS,u'sort-by'): ( + (TABLENS,u'field-number'), + ), + (TABLENS,u'source-cell-range'): ( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-service'): ( + (TABLENS,u'source-name'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'): ( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'): ( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'table-source'): ( + (XLINKNS,u'href'), + ), + (TABLENS,u'table-template'): ( + (TEXTNS,u'last-row-end-column'), + (TEXTNS,u'first-row-end-column'), + (TEXTNS,u'name'), + (TEXTNS,u'last-row-start-column'), + (TEXTNS,u'first-row-start-column'), + ), + (TEXTNS,u'a'): ( + (XLINKNS,u'href'), + ), +# required_attributes + (TEXTNS,u'alphabetical-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'): ( + (XLINKNS,u'href'), + ), + (TEXTNS,u'alphabetical-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'alphabetical-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'bibliography'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bibliography-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bibliography-mark'): ( + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bookmark'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'change'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'chapter'): ( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'): ( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-display'): ( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-name'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-next'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-number'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-select'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'dde-connection'): ( + (TEXTNS,u'connection-name'), + ), + (TEXTNS,u'dde-connection-decl'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'h'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'hidden-paragraph'): ( + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'): ( + (TEXTNS,u'string-value'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'illustration-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-bibliography'): ( + (TEXTNS,u'bibliography-data-field'), + ), + (TEXTNS,u'index-source-style'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'list-level-style-bullet'): ( + (TEXTNS,u'bullet-char'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-image'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-style'): ( + (STYLENS,u'name'), + ), + (TEXTNS,u'measure'): ( + (TEXTNS,u'kind'), + ), + (TEXTNS,u'note'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'note-ref'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'notes-configuration'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'object-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'object-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'outline-level-style'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'page'): ( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'): ( + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'placeholder'): ( + (TEXTNS,u'placeholder-type'), + ), + (TEXTNS,u'reference-mark'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'section'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decl'): ( + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), +# required_attributes + (TEXTNS,u'sort-key'): ( + (TEXTNS,u'key'), + ), + (TEXTNS,u'table-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-of-content'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-of-content-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'toc-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-defined'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-decl'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-input'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), +# required_attributes + (TEXTNS,u'user-index-mark'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'user-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-mark-start'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-source'): ( + (TEXTNS,u'index-name'), + ), + (TEXTNS,u'variable-decl'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'variable-input'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-set'): ( + (TEXTNS,u'name'), + ), +} + +# Empty list means the element has no allowed attributes +# None means anything goes + +allowed_attributes = { + (DCNS,u'creator'):( + ), + (DCNS,u'date'):( + ), + (DCNS,u'description'):( + ), + (DCNS,u'language'):( + ), + (DCNS,u'subject'):( + ), + (DCNS,u'title'):( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math'): None, + (XFORMSNS,u'model'): None, + (ANIMNS,u'animate'):( + (SMILNS,u'from'), + (SMILNS,u'calcMode'), + (SMILNS,u'keySplines'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'attributeName'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'values'), + (SMILNS,u'keyTimes'), + (SMILNS,u'additive'), + (ANIMNS,u'formula'), + (SMILNS,u'accumulate'), + (SMILNS,u'targetElement'), + (SMILNS,u'by'), + (SMILNS,u'fill'), + ), + (ANIMNS,u'animateColor'):( + (SMILNS,u'additive'), + (SMILNS,u'calcMode'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'attributeName'), + (ANIMNS,u'color-interpolation-direction'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'targetElement'), + (SMILNS,u'keyTimes'), + (ANIMNS,u'formula'), + (SMILNS,u'accumulate'), + (SMILNS,u'values'), + (SMILNS,u'fill'), + (SMILNS,u'by'), + (ANIMNS,u'color-interpolation'), + ), +# allowed_attributes + (ANIMNS,u'animateMotion'):( + (SVGNS,u'origin'), + (SMILNS,u'additive'), + (SMILNS,u'calcMode'), + (SMILNS,u'from'), + (SMILNS,u'values'), + (SMILNS,u'keySplines'), + (SMILNS,u'attributeName'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'targetElement'), + (SMILNS,u'keyTimes'), + (ANIMNS,u'formula'), + (SMILNS,u'accumulate'), + (SVGNS,u'path'), + (SMILNS,u'by'), + (SMILNS,u'fill'), + ), + (ANIMNS,u'animateTransform'):( + (SMILNS,u'additive'), + (SMILNS,u'from'), + (SMILNS,u'attributeName'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'targetElement'), + (ANIMNS,u'formula'), + (SMILNS,u'accumulate'), + (SMILNS,u'values'), + (SVGNS,u'type'), + (SMILNS,u'by'), + (SMILNS,u'fill'), + ), + (ANIMNS,u'audio'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'begin'), + (ANIMNS,u'audio-level'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'repeatDur'), + (SMILNS,u'repeatCount'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (XLINKNS,u'href'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'end'), + (SMILNS,u'dur'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'master-element'), + ), + (ANIMNS,u'command'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (ANIMNS,u'sub-item'), + (ANIMNS,u'command'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'targetElement'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'master-element'), + ), + (ANIMNS,u'iterate'):( + (SMILNS,u'decelerate'), + (SMILNS,u'repeatDur'), + (ANIMNS,u'iterate-interval'), + (SMILNS,u'repeatCount'), + (SMILNS,u'accelerate'), + (ANIMNS,u'id'), + (SMILNS,u'fill'), + (ANIMNS,u'iterate-type'), + (SMILNS,u'end'), + (SMILNS,u'endsync'), + (PRESENTATIONNS,u'preset-sub-type'), + (PRESENTATIONNS,u'preset-id'), + (SMILNS,u'restartDefault'), + (PRESENTATIONNS,u'master-element'), + (SMILNS,u'begin'), + (PRESENTATIONNS,u'preset-class'), + (SMILNS,u'targetElement'), + (SMILNS,u'dur'), + (SMILNS,u'restart'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'autoReverse'), + (SMILNS,u'fillDefault'), + ), + (ANIMNS,u'par'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'decelerate'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'accelerate'), + (SMILNS,u'repeatDur'), + (SMILNS,u'repeatCount'), + (SMILNS,u'autoReverse'), + (PRESENTATIONNS,u'preset-class'), + (SMILNS,u'fillDefault'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'restartDefault'), + (SMILNS,u'endsync'), + (SMILNS,u'dur'), + (SMILNS,u'fill'), + (ANIMNS,u'id'), + (SMILNS,u'restart'), + (PRESENTATIONNS,u'master-element'), + ), + (ANIMNS,u'param'):( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'seq'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'decelerate'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'accelerate'), + (SMILNS,u'repeatDur'), + (SMILNS,u'endsync'), + (SMILNS,u'restartDefault'), + (PRESENTATIONNS,u'preset-class'), + (SMILNS,u'fillDefault'), + (PRESENTATIONNS,u'preset-id'), + (SMILNS,u'autoReverse'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'repeatCount'), + (SMILNS,u'dur'), + (SMILNS,u'fill'), + (ANIMNS,u'id'), + (SMILNS,u'restart'), + (PRESENTATIONNS,u'master-element'), + ), + (ANIMNS,u'set'):( + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'targetElement'), + (SMILNS,u'accumulate'), + (SMILNS,u'fill'), + ), + (ANIMNS,u'transitionFilter'):( + (SMILNS,u'direction'), + (SMILNS,u'subtype'), + (SMILNS,u'additive'), + (SMILNS,u'calcMode'), + (SMILNS,u'from'), + (SMILNS,u'fadeColor'), + (SMILNS,u'to'), + (ANIMNS,u'sub-item'), + (SMILNS,u'targetElement'), + (SMILNS,u'mode'), + (ANIMNS,u'formula'), + (SMILNS,u'accumulate'), + (SMILNS,u'values'), + (SMILNS,u'type'), + (SMILNS,u'by'), + (SMILNS,u'fill'), + ), +# allowed_attributes + (CHARTNS,u'axis'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'dimension'), + (CHARTNS,u'name'), + ), + (CHARTNS,u'categories'):( + (TABLENS,u'cell-range-address'), + ), + (CHARTNS,u'chart'):( + (CHARTNS,u'column-mapping'), + (CHARTNS,u'row-mapping'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'data-point'):( + (CHARTNS,u'repeated'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'domain'):( + (TABLENS,u'cell-range-address'), + ), + (CHARTNS,u'error-indicator'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'floor'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), +# allowed_attributes + (CHARTNS,u'footer'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'grid'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'legend'):( + (CHARTNS,u'legend-align'), + (STYLENS,u'legend-expansion-aspect-ratio'), + (STYLENS,u'legend-expansion'), + (CHARTNS,u'legend-position'), + (CHARTNS,u'style-name'), + (SVGNS,u'y'), + (SVGNS,u'x'), + ), + (CHARTNS,u'mean-value'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'plot-area'):( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'vrp'), + (DR3DNS,u'focal-length'), + (CHARTNS,u'data-source-has-labels'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'transform'), + (DR3DNS,u'shadow-slant'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + (DR3DNS,u'vup'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (DR3DNS,u'vpn'), + (TABLENS,u'cell-range-address'), + (DR3DNS,u'projection'), + ), + (CHARTNS,u'regression-curve'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'series'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'attached-axis'), + (CHARTNS,u'values-cell-range-address'), + (CHARTNS,u'label-cell-address'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'stock-gain-marker'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'stock-loss-marker'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'stock-range-line'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'subtitle'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'symbol-image'):( + (XLINKNS,u'href'), + ), + (CHARTNS,u'title'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'wall'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), + (CONFIGNS,u'config-item'):( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-entry'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'):( + (CONFIGNS,u'name'), + ), +# allowed_attributes + (NUMBERNS,u'am-pm'):( + ), + (NUMBERNS,u'boolean'):( + ), + (NUMBERNS,u'boolean-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'currency-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'automatic-order'), + ), + (NUMBERNS,u'currency-symbol'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + ), + (NUMBERNS,u'date-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (NUMBERNS,u'format-source'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'automatic-order'), + ), + (NUMBERNS,u'day'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'day-of-week'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'embedded-text'):( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'era'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'fraction'):( + (NUMBERNS,u'grouping'), + (NUMBERNS,u'min-denominator-digits'), + (NUMBERNS,u'min-numerator-digits'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'denominator-value'), + ), + (NUMBERNS,u'hours'):( + (NUMBERNS,u'style'), + ), + (NUMBERNS,u'minutes'):( + (NUMBERNS,u'style'), + ), + (NUMBERNS,u'month'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + (NUMBERNS,u'possessive-form'), + (NUMBERNS,u'textual'), + ), + (NUMBERNS,u'number'):( + (NUMBERNS,u'display-factor'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'decimal-replacement'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'number-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), +# allowed_attributes + (NUMBERNS,u'percentage-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'quarter'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'scientific-number'):( + (NUMBERNS,u'min-exponent-digits'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'seconds'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'decimal-places'), + ), + (NUMBERNS,u'text'):( + ), + (NUMBERNS,u'text-content'):( + ), + (NUMBERNS,u'text-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'time-style'):( + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-format'), + (STYLENS,u'name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'truncate-on-overflow'), + (NUMBERNS,u'transliteration-style'), + (NUMBERNS,u'format-source'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'week-of-year'):( + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'year'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (DR3DNS,u'cube'):( + (DR3DNS,u'min-edge'), + (DR3DNS,u'max-edge'), + (DRAWNS,u'layer'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), + (DR3DNS,u'extrude'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), + (DR3DNS,u'light'):( + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'direction'), + (DR3DNS,u'specular'), + (DR3DNS,u'enabled'), + ), + (DR3DNS,u'rotate'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), +# allowed_attributes + (DR3DNS,u'scene'):( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'focal-length'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'projection'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'shadow-slant'), + (DR3DNS,u'transform'), + (DR3DNS,u'vpn'), + (DR3DNS,u'vrp'), + (DR3DNS,u'vup'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DR3DNS,u'sphere'):( + (DRAWNS,u'layer'), + (DR3DNS,u'center'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (DR3DNS,u'size'), + ), + (DRAWNS,u'a'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (OFFICENS,u'server-map'), + ), + (DRAWNS,u'applet'):( + (DRAWNS,u'code'), + (XLINKNS,u'show'), + (DRAWNS,u'object'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'archive'), + (DRAWNS,u'may-script'), + ), + (DRAWNS,u'area-circle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (SVGNS,u'cx'), + (XLINKNS,u'type'), + (DRAWNS,u'nohref'), + (SVGNS,u'cy'), + (XLINKNS,u'href'), + (SVGNS,u'r'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'area-polygon'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + (SVGNS,u'viewBox'), + (DRAWNS,u'points'), + ), + (DRAWNS,u'area-rectangle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'caption'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'transform'), + (TABLENS,u'end-y'), + (DRAWNS,u'corner-radius'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'circle'):( + (DRAWNS,u'end-angle'), + (DRAWNS,u'id'), + (DRAWNS,u'kind'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'start-angle'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'cx'), + (SVGNS,u'cy'), + (SVGNS,u'height'), + (SVGNS,u'r'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'connector'):( + (DRAWNS,u'layer'), + (DRAWNS,u'end-shape'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (TABLENS,u'end-y'), + (TABLENS,u'end-x'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'type'), + (DRAWNS,u'start-shape'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'style-name'), + (DRAWNS,u'start-glue-point'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (TEXTNS,u'anchor-type'), + (DRAWNS,u'line-skew'), + (DRAWNS,u'name'), + (DRAWNS,u'end-glue-point'), + (DRAWNS,u'text-style-name'), + ), + (DRAWNS,u'contour-path'):( + (SVGNS,u'd'), + (SVGNS,u'width'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'contour-polygon'):( + (SVGNS,u'width'), + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'control'):( + (DRAWNS,u'control'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'custom-shape'):( + (DRAWNS,u'engine'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'data'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'ellipse'):( + (DRAWNS,u'layer'), + (DRAWNS,u'start-angle'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (SVGNS,u'rx'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (SVGNS,u'width'), + (TABLENS,u'end-y'), + (TABLENS,u'end-x'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'end-angle'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (TEXTNS,u'anchor-type'), + (SVGNS,u'ry'), + (DRAWNS,u'kind'), + (DRAWNS,u'name'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'text-style-name'), + ), + (DRAWNS,u'enhanced-geometry'):( + (DRAWNS,u'extrusion-rotation-center'), + (DRAWNS,u'extrusion-shininess'), + (DRAWNS,u'extrusion-rotation-angle'), + (DRAWNS,u'extrusion-allowed'), + (DRAWNS,u'extrusion-first-light-level'), + (DRAWNS,u'extrusion-specularity'), + (DRAWNS,u'extrusion-viewpoint'), + (DRAWNS,u'extrusion-second-light-level'), + (DRAWNS,u'extrusion-origin'), + (DRAWNS,u'extrusion-color'), + (SVGNS,u'viewBox'), + (DR3DNS,u'projection'), + (DRAWNS,u'extrusion-metal'), + (DRAWNS,u'extrusion-number-of-line-segments'), + (DRAWNS,u'text-path-same-letter-heights'), + (DRAWNS,u'extrusion-first-light-harsh'), + (DRAWNS,u'enhanced-path'), + (DRAWNS,u'text-rotate-angle'), + (DRAWNS,u'type'), + (DRAWNS,u'glue-point-leaving-directions'), + (DRAWNS,u'concentric-gradient-fill-allowed'), + (DRAWNS,u'text-path-scale'), + (DRAWNS,u'extrusion-brightness'), + (DRAWNS,u'extrusion-first-light-direction'), + (DRAWNS,u'extrusion-light-face'), + (DRAWNS,u'text-path-allowed'), + (DRAWNS,u'glue-points'), + (DRAWNS,u'mirror-vertical'), + (DRAWNS,u'extrusion-depth'), + (DRAWNS,u'extrusion-diffusion'), + (DRAWNS,u'extrusion-second-light-direction'), + (DRAWNS,u'extrusion-skew'), + (DR3DNS,u'shade-mode'), + (DRAWNS,u'path-stretchpoint-y'), + (DRAWNS,u'modifiers'), + (DRAWNS,u'extrusion'), + (DRAWNS,u'path-stretchpoint-x'), + (DRAWNS,u'text-areas'), + (DRAWNS,u'mirror-horizontal'), + (DRAWNS,u'text-path-mode'), + (DRAWNS,u'extrusion-second-light-harsh'), + (DRAWNS,u'glue-point-type'), + (DRAWNS,u'text-path'), + ), + (DRAWNS,u'equation'):( + (DRAWNS,u'formula'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'fill-image'):( + (DRAWNS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (DRAWNS,u'display-name'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'floating-frame'):( + (XLINKNS,u'href'), + (XLINKNS,u'actuate'), + (DRAWNS,u'frame-name'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'frame'):( + (DRAWNS,u'copy-of'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'user-transformed'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'g'):( + (DRAWNS,u'id'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'glue-point'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'align'), + (DRAWNS,u'id'), + ), + (DRAWNS,u'gradient'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'end-color'), + (DRAWNS,u'start-color'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + (DRAWNS,u'end-intensity'), + (DRAWNS,u'start-intensity'), + ), + (DRAWNS,u'handle'):( + (DRAWNS,u'handle-radius-range-minimum'), + (DRAWNS,u'handle-switched'), + (DRAWNS,u'handle-range-y-maximum'), + (DRAWNS,u'handle-mirror-horizontal'), + (DRAWNS,u'handle-range-x-maximum'), + (DRAWNS,u'handle-mirror-vertical'), + (DRAWNS,u'handle-range-y-minimum'), + (DRAWNS,u'handle-radius-range-maximum'), + (DRAWNS,u'handle-range-x-minimum'), + (DRAWNS,u'handle-position'), + (DRAWNS,u'handle-polar'), + ), + (DRAWNS,u'hatch'):( + (DRAWNS,u'distance'), + (DRAWNS,u'style'), + (DRAWNS,u'name'), + (DRAWNS,u'color'), + (DRAWNS,u'display-name'), + (DRAWNS,u'rotation'), + ), + (DRAWNS,u'image'):( + (DRAWNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'image-map'):( + ), + (DRAWNS,u'layer'):( + (DRAWNS,u'protected'), + (DRAWNS,u'name'), + (DRAWNS,u'display'), + ), + (DRAWNS,u'layer-set'):( + ), + (DRAWNS,u'line'):( + (DRAWNS,u'class-names'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'x1'), + (SVGNS,u'x2'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'marker'):( + (SVGNS,u'd'), + (DRAWNS,u'display-name'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), +# allowed_attributes + (DRAWNS,u'measure'):( + (TABLENS,u'end-cell-address'), + (DRAWNS,u'layer'), + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (TABLENS,u'table-background'), + (SVGNS,u'x2'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y1'), + (TABLENS,u'end-y'), + (SVGNS,u'x1'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'object'):( + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (DRAWNS,u'notify-on-update-of-ranges'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'object-ole'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'class-id'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'opacity'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'start'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'end'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + ), + (DRAWNS,u'page'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (DRAWNS,u'name'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (DRAWNS,u'master-page-name'), + (DRAWNS,u'id'), + (PRESENTATIONNS,u'use-date-time-name'), + ), + (DRAWNS,u'page-thumbnail'):( + (TABLENS,u'table-background'), + (PRESENTATIONNS,u'user-transformed'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (DRAWNS,u'page-number'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'class'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'param'):( + (DRAWNS,u'name'), + (DRAWNS,u'value'), + ), + (DRAWNS,u'path'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (SVGNS,u'd'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-type'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'plugin'):( + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (DRAWNS,u'mime-type'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'polygon'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'polyline'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'rect'):( + (DRAWNS,u'corner-radius'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'regular-polygon'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TEXTNS,u'anchor-page-number'), + (DRAWNS,u'concave'), + (DRAWNS,u'sharpness'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (DRAWNS,u'corners'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'stroke-dash'):( + (DRAWNS,u'distance'), + (DRAWNS,u'dots1-length'), + (DRAWNS,u'name'), + (DRAWNS,u'dots2-length'), + (DRAWNS,u'style'), + (DRAWNS,u'dots1'), + (DRAWNS,u'display-name'), + (DRAWNS,u'dots2'), + ), + (DRAWNS,u'text-box'):( + (FONS,u'min-width'), + (DRAWNS,u'corner-radius'), + (FONS,u'max-height'), + (FONS,u'min-height'), + (DRAWNS,u'chain-next-name'), + (FONS,u'max-width'), + ), + (FORMNS,u'button'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'focus-on-click'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'default-button'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + (FORMNS,u'toggle'), + (FORMNS,u'xforms-submission'), + (OFFICENS,u'target-frame'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'checkbox'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'is-tristate'), + (FORMNS,u'current-state'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'state'), + (FORMNS,u'visual-effect'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'column'):( + (FORMNS,u'control-implementation'), + (FORMNS,u'text-style-name'), + (FORMNS,u'name'), + (FORMNS,u'label'), + ), + (FORMNS,u'combobox'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'dropdown'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'tab-index'), + (FORMNS,u'auto-complete'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'list-source'), + (FORMNS,u'title'), + (FORMNS,u'list-source-type'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + (FORMNS,u'size'), + ), + (FORMNS,u'connection-resource'):( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'file'):( + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'fixed-text'):( + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'multi-line'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), + (FORMNS,u'form'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (FORMNS,u'allow-deletes'), + (FORMNS,u'command-type'), + (FORMNS,u'apply-filter'), + (XLINKNS,u'type'), + (FORMNS,u'method'), + (OFFICENS,u'target-frame'), + (FORMNS,u'navigation-mode'), + (FORMNS,u'detail-fields'), + (FORMNS,u'master-fields'), + (FORMNS,u'allow-updates'), + (FORMNS,u'name'), + (FORMNS,u'tab-cycle'), + (FORMNS,u'control-implementation'), + (FORMNS,u'escape-processing'), + (FORMNS,u'filter'), + (FORMNS,u'command'), + (FORMNS,u'datasource'), + (FORMNS,u'enctype'), + (FORMNS,u'allow-inserts'), + (FORMNS,u'ignore-result'), + (FORMNS,u'order'), + ), + (FORMNS,u'formatted-text'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'max-value'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'min-value'), + (FORMNS,u'validation'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'frame'):( + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), + (FORMNS,u'generic-control'):( + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + (FORMNS,u'id'), + ), + (FORMNS,u'grid'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), + (FORMNS,u'hidden'):( + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + (FORMNS,u'value'), + (FORMNS,u'id'), + ), + (FORMNS,u'image'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (OFFICENS,u'target-frame'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + (FORMNS,u'id'), + ), + (FORMNS,u'image-frame'):( + (FORMNS,u'name'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'readonly'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (FORMNS,u'id'), + ), + (FORMNS,u'item'):( + (FORMNS,u'label'), + ), + (FORMNS,u'list-property'):( + (FORMNS,u'property-name'), + (OFFICENS,u'value-type'), + ), + (FORMNS,u'list-value'):( + (OFFICENS,u'string-value'), + ), +# allowed_attributes + (FORMNS,u'listbox'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'bound-column'), + (FORMNS,u'multiple'), + (FORMNS,u'name'), + (FORMNS,u'dropdown'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'tab-index'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'list-source'), + (FORMNS,u'title'), + (FORMNS,u'list-source-type'), + (FORMNS,u'id'), + (FORMNS,u'xforms-list-source'), + (FORMNS,u'size'), + ), + (FORMNS,u'number'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'option'):( + (FORMNS,u'current-selected'), + (FORMNS,u'selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + ), + (FORMNS,u'password'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'echo-char'), + (FORMNS,u'id'), + ), + (FORMNS,u'properties'):( + ), + (FORMNS,u'property'):( + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (FORMNS,u'property-name'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (OFFICENS,u'time-value'), + ), + (FORMNS,u'radio'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'selected'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'current-selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'title'), + (FORMNS,u'visual-effect'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'text'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'textarea'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'time'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'value-range'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'max-value'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'orientation'), + (FORMNS,u'page-step-size'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'min-value'), + (FORMNS,u'id'), + (FORMNS,u'step-size'), + ), + (MANIFESTNS,'algorithm') : ( + (MANIFESTNS,'algorithm-name'), + (MANIFESTNS,'initialisation-vector'), + ), + (MANIFESTNS,'encryption-data') : ( + (MANIFESTNS,'checksum-type'), + (MANIFESTNS,'checksum'), + ), + (MANIFESTNS,'file-entry') : ( + (MANIFESTNS,'full-path'), + (MANIFESTNS,'media-type'), + (MANIFESTNS,'size'), + ), + (MANIFESTNS,'key-derivation') : ( + (MANIFESTNS,'key-derivation-name'), + (MANIFESTNS,'salt'), + (MANIFESTNS,'iteration-count'), + ), +# allowed_attributes + (METANS,u'auto-reload'):( + (METANS,u'delay'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + ), + (METANS,u'creation-date'):( + ), + (METANS,u'date-string'):( + ), + (METANS,u'document-statistic'):( + (METANS,u'non-whitespace-character-count'), + (METANS,u'ole-object-count'), + (METANS,u'table-count'), + (METANS,u'row-count'), + (METANS,u'character-count'), + (METANS,u'sentence-count'), + (METANS,u'draw-count'), + (METANS,u'paragraph-count'), + (METANS,u'word-count'), + (METANS,u'object-count'), + (METANS,u'syllable-count'), + (METANS,u'image-count'), + (METANS,u'page-count'), + (METANS,u'frame-count'), + (METANS,u'cell-count'), + ), + (METANS,u'editing-cycles'):( + ), + (METANS,u'editing-duration'):( + ), + (METANS,u'generator'):( + ), + (METANS,u'hyperlink-behaviour'):( + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'show'), + ), + (METANS,u'initial-creator'):( + ), + (METANS,u'keyword'):( + ), + (METANS,u'print-date'):( + ), + (METANS,u'printed-by'):( + ), + (METANS,u'template'):( + (METANS,u'date'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'title'), + ), + (METANS,u'user-defined'):( + (METANS,u'name'), + (METANS,u'value-type'), + ), + (OFFICENS,u'annotation'):( + (DRAWNS,u'layer'), + (SVGNS,u'height'), + (TEXTNS,u'anchor-page-number'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (SVGNS,u'width'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'style-name'), + (TEXTNS,u'anchor-type'), + (DRAWNS,u'name'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'corner-radius'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (OFFICENS,u'display'), + ), + (OFFICENS,u'automatic-styles'):( + ), + (OFFICENS,u'binary-data'):( + ), + (OFFICENS,u'body'):( + ), + (OFFICENS,u'change-info'):( + ), + (OFFICENS,u'chart'):( + ), + (OFFICENS,u'dde-source'):( + (OFFICENS,u'dde-application'), + (OFFICENS,u'automatic-update'), + (OFFICENS,u'conversion-mode'), + (OFFICENS,u'dde-item'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'name'), + ), + (OFFICENS,u'document'):( + (OFFICENS,u'mimetype'), + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-content'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-meta'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-settings'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-styles'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'drawing'):( + ), + (OFFICENS,u'event-listeners'):( + ), + (OFFICENS,u'font-face-decls'):( + ), + (OFFICENS,u'forms'):( + (FORMNS,u'automatic-focus'), + (FORMNS,u'apply-design-mode'), + ), + (OFFICENS,u'image'):( + ), + (OFFICENS,u'master-styles'):( + ), + (OFFICENS,u'meta'):( + ), + (OFFICENS,u'presentation'):( + ), + (OFFICENS,u'script'):( + (SCRIPTNS,u'language'), + ), + (OFFICENS,u'scripts'):( + ), + (OFFICENS,u'settings'):( + ), + (OFFICENS,u'spreadsheet'):( + (TABLENS,u'structure-protected'), + (TABLENS,u'protection-key'), + ), + (OFFICENS,u'styles'):( + ), + (OFFICENS,u'text'):( + (TEXTNS,u'global'), + ), + (PRESENTATIONNS,u'animation-group'):( + ), + (PRESENTATIONNS,u'animations'):( + ), + (PRESENTATIONNS,u'date-time'):( + ), + (PRESENTATIONNS,u'date-time-decl'):( + (PRESENTATIONNS,u'source'), + (STYLENS,u'data-style-name'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'):( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'event-listener'):( + (PRESENTATIONNS,u'direction'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (PRESENTATIONNS,u'effect'), + (SCRIPTNS,u'event-name'), + (PRESENTATIONNS,u'start-scale'), + (XLINKNS,u'href'), + (PRESENTATIONNS,u'verb'), + (PRESENTATIONNS,u'action'), + (PRESENTATIONNS,u'speed'), + ), + (PRESENTATIONNS,u'footer'):( + ), + (PRESENTATIONNS,u'footer-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header'):( + ), + (PRESENTATIONNS,u'header-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'hide-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'notes'):( + (STYLENS,u'page-layout-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + (PRESENTATIONNS,u'use-footer-name'), + ), + (PRESENTATIONNS,u'placeholder'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'):( + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), +# allowed_attributes + (PRESENTATIONNS,u'settings'):( + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'endless'), + (PRESENTATIONNS,u'force-manual'), + (PRESENTATIONNS,u'full-screen'), + (PRESENTATIONNS,u'mouse-as-pen'), + (PRESENTATIONNS,u'mouse-visible'), + (PRESENTATIONNS,u'pause'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'show-end-of-presentation-slide'), + (PRESENTATIONNS,u'show-logo'), + (PRESENTATIONNS,u'start-page'), + (PRESENTATIONNS,u'start-with-navigator'), + (PRESENTATIONNS,u'stay-on-top'), + (PRESENTATIONNS,u'transition-on-click'), + ), + (PRESENTATIONNS,u'show'):( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (PRESENTATIONNS,u'play-full'), + (XLINKNS,u'show'), + ), + (SCRIPTNS,u'event-listener'):( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'macro-name'), + (XLINKNS,u'actuate'), + (SCRIPTNS,u'event-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (STYLENS,u'background-image'):( + (DRAWNS,u'opacity'), + (STYLENS,u'repeat'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (STYLENS,u'filter-name'), + (XLINKNS,u'href'), + (STYLENS,u'position'), + (XLINKNS,u'type'), + ), + (STYLENS,u'chart-properties'): ( + (CHARTNS,u'connect-bars'), + (CHARTNS,u'data-label-number'), + (CHARTNS,u'data-label-symbol'), + (CHARTNS,u'data-label-text'), + (CHARTNS,u'deep'), + (CHARTNS,u'display-label'), + (CHARTNS,u'error-category'), + (CHARTNS,u'error-lower-indicator'), + (CHARTNS,u'error-lower-limit'), + (CHARTNS,u'error-margin'), + (CHARTNS,u'error-percentage'), + (CHARTNS,u'error-upper-indicator'), + (CHARTNS,u'error-upper-limit'), + (CHARTNS,u'gap-width'), + (CHARTNS,u'interpolation'), + (CHARTNS,u'interval-major'), + (CHARTNS,u'interval-minor'), + (CHARTNS,u'japanese-candle-stick'), + (CHARTNS,u'label-arrangement'), + (CHARTNS,u'lines'), + (CHARTNS,u'link-data-style-to-source'), + (CHARTNS,u'logarithmic'), + (CHARTNS,u'maximum'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'minimum'), + (CHARTNS,u'origin'), + (CHARTNS,u'overlap'), + (CHARTNS,u'percentage'), + (CHARTNS,u'pie-offset'), + (CHARTNS,u'regression-type'), + (CHARTNS,u'scale-text'), + (CHARTNS,u'series-source'), + (CHARTNS,u'solid-type'), + (CHARTNS,u'spline-order'), + (CHARTNS,u'spline-resolution'), + (CHARTNS,u'stacked'), + (CHARTNS,u'symbol-height'), + (CHARTNS,u'symbol-type'), + (CHARTNS,u'symbol-width'), + (CHARTNS,u'text-overlap'), + (CHARTNS,u'three-dimensional'), + (CHARTNS,u'tick-marks-major-inner'), + (CHARTNS,u'tick-marks-major-outer'), + (CHARTNS,u'tick-marks-minor-inner'), + (CHARTNS,u'tick-marks-minor-outer'), + (CHARTNS,u'vertical'), + (CHARTNS,u'visible'), + (STYLENS,u'direction'), + (STYLENS,u'rotation-angle'), + (TEXTNS,u'line-break'), + ), + (STYLENS,u'column'):( + (FONS,u'end-indent'), + (FONS,u'space-before'), + (FONS,u'start-indent'), + (FONS,u'space-after'), + (STYLENS,u'rel-width'), + ), + (STYLENS,u'column-sep'):( + (STYLENS,u'color'), + (STYLENS,u'width'), + (STYLENS,u'style'), + (STYLENS,u'vertical-align'), + (STYLENS,u'height'), + ), + (STYLENS,u'columns'):( + (FONS,u'column-count'), + (FONS,u'column-gap'), + ), + (STYLENS,u'default-style'):( + (STYLENS,u'family'), + ), + (STYLENS,u'drawing-page-properties'): ( + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-name'), + (STYLENS,u'repeat'), + (DRAWNS,u'fill-image-width'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (SVGNS,u'fill-rule'), + (PRESENTATIONNS,u'transition-type'), + (PRESENTATIONNS,u'transition-style'), + (PRESENTATIONNS,u'transition-speed'), + (SMILNS,u'type'), + (SMILNS,u'subtype'), + (SMILNS,u'direction'), + (SMILNS,u'fadeColor'), + (PRESENTATIONNS,u'duration'), + (PRESENTATIONNS,u'visibility'), + (DRAWNS,u'background-size'), + (PRESENTATIONNS,u'background-objects-visible'), + (PRESENTATIONNS,u'background-visible'), + (PRESENTATIONNS,u'display-header'), + (PRESENTATIONNS,u'display-footer'), + (PRESENTATIONNS,u'display-page-number'), + (PRESENTATIONNS,u'display-date-time'), + ), + (STYLENS,u'drop-cap'):( + (STYLENS,u'distance'), + (STYLENS,u'length'), + (STYLENS,u'style-name'), + (STYLENS,u'lines'), + ), + (STYLENS,u'font-face'):( + (STYLENS,u'font-adornments'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-pitch'), + (STYLENS,u'name'), + (SVGNS,u'accent-height'), + (SVGNS,u'alphabetic'), + (SVGNS,u'ascent'), + (SVGNS,u'bbox'), + (SVGNS,u'cap-height'), + (SVGNS,u'descent'), + (SVGNS,u'font-family'), + (SVGNS,u'font-size'), + (SVGNS,u'font-stretch'), + (SVGNS,u'font-style'), + (SVGNS,u'font-variant'), + (SVGNS,u'font-weight'), + (SVGNS,u'hanging'), + (SVGNS,u'ideographic'), + (SVGNS,u'mathematical'), + (SVGNS,u'overline-position'), + (SVGNS,u'overline-thickness'), + (SVGNS,u'panose-1'), + (SVGNS,u'slope'), + (SVGNS,u'stemh'), + (SVGNS,u'stemv'), + (SVGNS,u'strikethrough-position'), + (SVGNS,u'strikethrough-thickness'), + (SVGNS,u'underline-position'), + (SVGNS,u'underline-thickness'), + (SVGNS,u'unicode-range'), + (SVGNS,u'units-per-em'), + (SVGNS,u'v-alphabetic'), + (SVGNS,u'v-hanging'), + (SVGNS,u'v-ideographic'), + (SVGNS,u'v-mathematical'), + (SVGNS,u'widths'), + (SVGNS,u'x-height'), + ), + (STYLENS,u'footer'):( + (STYLENS,u'display'), + (STYLENS,u'dynamic-spacing'), + ), + (STYLENS,u'footer-left'):( + (STYLENS,u'display'), + (STYLENS,u'dynamic-spacing'), + ), + (STYLENS,u'footer-style'):( + ), + (STYLENS,u'footnote-sep'):( + (STYLENS,u'distance-after-sep'), + (STYLENS,u'color'), + (STYLENS,u'rel-width'), + (STYLENS,u'width'), + (STYLENS,u'distance-before-sep'), + (STYLENS,u'line-style'), + (STYLENS,u'adjustment'), + ), +# allowed_attributes + (STYLENS,u'graphic-properties'): ( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'back-scale'), + (DR3DNS,u'backface-culling'), + (DR3DNS,u'close-back'), + (DR3DNS,u'close-front'), + (DR3DNS,u'depth'), + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'edge-rounding'), + (DR3DNS,u'edge-rounding-mode'), + (DR3DNS,u'emissive-color'), + (DR3DNS,u'end-angle'), + (DR3DNS,u'horizontal-segments'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'normals-direction'), + (DR3DNS,u'normals-kind'), + (DR3DNS,u'shadow'), + (DR3DNS,u'shininess'), + (DR3DNS,u'specular-color'), + (DR3DNS,u'texture-filter'), + (DR3DNS,u'texture-generation-mode-x'), + (DR3DNS,u'texture-generation-mode-y'), + (DR3DNS,u'texture-kind'), + (DR3DNS,u'texture-mode'), + (DR3DNS,u'vertical-segments'), + (DRAWNS,u'auto-grow-height'), + (DRAWNS,u'auto-grow-width'), + (DRAWNS,u'blue'), + (DRAWNS,u'caption-angle'), + (DRAWNS,u'caption-angle-type'), + (DRAWNS,u'caption-escape'), + (DRAWNS,u'caption-escape-direction'), + (DRAWNS,u'caption-fit-line-length'), + (DRAWNS,u'caption-gap'), + (DRAWNS,u'caption-line-length'), + (DRAWNS,u'caption-type'), + (DRAWNS,u'color-inversion'), + (DRAWNS,u'color-mode'), + (DRAWNS,u'contrast'), + (DRAWNS,u'decimal-places'), + (DRAWNS,u'end-guide'), + (DRAWNS,u'end-line-spacing-horizontal'), + (DRAWNS,u'end-line-spacing-vertical'), + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-name'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-width'), +# allowed_attributes + (DRAWNS,u'fit-to-contour'), + (DRAWNS,u'fit-to-size'), + (DRAWNS,u'frame-display-border'), + (DRAWNS,u'frame-display-scrollbar'), + (DRAWNS,u'frame-margin-horizontal'), + (DRAWNS,u'frame-margin-vertical'), + (DRAWNS,u'gamma'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'green'), + (DRAWNS,u'guide-distance'), + (DRAWNS,u'guide-overhang'), + (DRAWNS,u'image-opacity'), + (DRAWNS,u'line-distance'), + (DRAWNS,u'luminance'), + (DRAWNS,u'marker-end'), + (DRAWNS,u'marker-end-center'), + (DRAWNS,u'marker-end-width'), + (DRAWNS,u'marker-start'), + (DRAWNS,u'marker-start-center'), + (DRAWNS,u'marker-start-width'), + (DRAWNS,u'measure-align'), + (DRAWNS,u'measure-vertical-align'), + (DRAWNS,u'ole-draw-aspect'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (DRAWNS,u'parallel'), + (DRAWNS,u'placing'), + (DRAWNS,u'red'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'shadow'), + (DRAWNS,u'shadow-color'), + (DRAWNS,u'shadow-offset-x'), + (DRAWNS,u'shadow-offset-y'), + (DRAWNS,u'shadow-opacity'), + (DRAWNS,u'show-unit'), + (DRAWNS,u'start-guide'), + (DRAWNS,u'start-line-spacing-horizontal'), + (DRAWNS,u'start-line-spacing-vertical'), + (DRAWNS,u'stroke'), + (DRAWNS,u'stroke-dash'), + (DRAWNS,u'stroke-dash-names'), + (DRAWNS,u'stroke-linejoin'), + (DRAWNS,u'symbol-color'), + (DRAWNS,u'textarea-horizontal-align'), + (DRAWNS,u'textarea-vertical-align'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'unit'), + (DRAWNS,u'visible-area-height'), + (DRAWNS,u'visible-area-left'), + (DRAWNS,u'visible-area-top'), + (DRAWNS,u'visible-area-width'), + (DRAWNS,u'wrap-influence-on-position'), +# allowed_attributes + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'clip'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'max-height'), + (FONS,u'max-width'), + (FONS,u'min-height'), + (FONS,u'min-width'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'editable'), + (STYLENS,u'flow-with-text'), + (STYLENS,u'horizontal-pos'), + (STYLENS,u'horizontal-rel'), + (STYLENS,u'mirror'), + (STYLENS,u'number-wrapped-paragraphs'), + (STYLENS,u'overflow-behavior'), + (STYLENS,u'print-content'), + (STYLENS,u'protect'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (STYLENS,u'repeat'), + (STYLENS,u'run-through'), + (STYLENS,u'shadow'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (STYLENS,u'wrap'), + (STYLENS,u'wrap-contour'), + (STYLENS,u'wrap-contour-mode'), + (STYLENS,u'wrap-dynamic-threshold'), + (SVGNS,u'fill-rule'), + (SVGNS,u'height'), + (SVGNS,u'stroke-color'), + (SVGNS,u'stroke-opacity'), + (SVGNS,u'stroke-width'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (TEXTNS,u'animation'), + (TEXTNS,u'animation-delay'), + (TEXTNS,u'animation-direction'), + (TEXTNS,u'animation-repeat'), + (TEXTNS,u'animation-start-inside'), + (TEXTNS,u'animation-steps'), + (TEXTNS,u'animation-stop-inside'), + ), + (STYLENS,u'handout-master'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (STYLENS,u'page-layout-name'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + ), + (STYLENS,u'header'):( + (STYLENS,u'display'), + (STYLENS,u'dynamic-spacing'), + ), + (STYLENS,u'header-footer-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'min-height'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'dynamic-spacing'), + (STYLENS,u'shadow'), + (SVGNS,u'height'), + ), + (STYLENS,u'header-left'):( + (STYLENS,u'display'), + (STYLENS,u'dynamic-spacing'), + ), + (STYLENS,u'header-style'):( + ), +# allowed_attributes + (STYLENS,u'list-level-properties'): ( + (FONS,u'height'), + (FONS,u'text-align'), + (FONS,u'width'), + (STYLENS,u'font-name'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (TEXTNS,u'min-label-distance'), + (TEXTNS,u'min-label-width'), + (TEXTNS,u'space-before'), + ), + (STYLENS,u'map'):( + (STYLENS,u'apply-style-name'), + (STYLENS,u'base-cell-address'), + (STYLENS,u'condition'), + ), + (STYLENS,u'master-page'):( + (STYLENS,u'page-layout-name'), + (STYLENS,u'display-name'), + (DRAWNS,u'style-name'), + (STYLENS,u'name'), + (STYLENS,u'next-style-name'), + ), + (STYLENS,u'page-layout'):( + (STYLENS,u'name'), + (STYLENS,u'page-usage'), + ), + (STYLENS,u'page-layout-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'page-height'), + (FONS,u'page-width'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'first-page-number'), + (STYLENS,u'footnote-max-height'), + (STYLENS,u'layout-grid-base-height'), + (STYLENS,u'layout-grid-color'), + (STYLENS,u'layout-grid-display'), + (STYLENS,u'layout-grid-lines'), + (STYLENS,u'layout-grid-mode'), + (STYLENS,u'layout-grid-print'), + (STYLENS,u'layout-grid-ruby-below'), + (STYLENS,u'layout-grid-ruby-height'), + (STYLENS,u'name'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (STYLENS,u'page-usage'), + (STYLENS,u'paper-tray-name'), + (STYLENS,u'print'), + (STYLENS,u'print-orientation'), + (STYLENS,u'print-page-order'), + (STYLENS,u'register-truth-ref-style-name'), + (STYLENS,u'scale-to'), + (STYLENS,u'scale-to-pages'), + (STYLENS,u'shadow'), + (STYLENS,u'table-centering'), + (STYLENS,u'writing-mode'), + ), + (STYLENS,u'paragraph-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'hyphenation-keep'), + (FONS,u'hyphenation-ladder-count'), + (FONS,u'keep-together'), + (FONS,u'keep-with-next'), + (FONS,u'line-height'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'orphans'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'text-align'), + (FONS,u'text-align-last'), + (FONS,u'text-indent'), + (FONS,u'widows'), + (STYLENS,u'auto-text-indent'), + (STYLENS,u'background-transparency'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'font-independent-line-spacing'), + (STYLENS,u'justify-single-word'), + (STYLENS,u'line-break'), + (STYLENS,u'line-height-at-least'), + (STYLENS,u'line-spacing'), + (STYLENS,u'page-number'), + (STYLENS,u'punctuation-wrap'), + (STYLENS,u'register-true'), + (STYLENS,u'shadow'), + (STYLENS,u'snap-to-layout-grid'), + (STYLENS,u'tab-stop-distance'), + (STYLENS,u'text-autospace'), + (STYLENS,u'vertical-align'), + (STYLENS,u'writing-mode'), + (STYLENS,u'writing-mode-automatic'), + (TEXTNS,u'line-number'), + (TEXTNS,u'number-lines'), + ), + (STYLENS,u'presentation-page-layout'):( + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), +# allowed_attributes + (STYLENS,u'region-center'):( + ), + (STYLENS,u'region-left'):( + ), + (STYLENS,u'region-right'):( + ), + (STYLENS,u'ruby-properties'): ( + (STYLENS,u'ruby-position'), + (STYLENS,u'ruby-align'), + ), + (STYLENS,u'section-properties'): ( + (FONS,u'background-color'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (STYLENS,u'protect'), + (STYLENS,u'writing-mode'), + (TEXTNS,u'dont-balance-text-columns'), + ), + (STYLENS,u'style'):( + (STYLENS,u'family'), + (STYLENS,u'list-style-name'), + (STYLENS,u'name'), + (STYLENS,u'auto-update'), + (STYLENS,u'default-outline-level'), + (STYLENS,u'class'), + (STYLENS,u'next-style-name'), + (STYLENS,u'data-style-name'), + (STYLENS,u'master-page-name'), + (STYLENS,u'display-name'), + (STYLENS,u'parent-style-name'), + ), + (STYLENS,u'tab-stop'):( + (STYLENS,u'leader-text-style'), + (STYLENS,u'leader-width'), + (STYLENS,u'leader-style'), + (STYLENS,u'char'), + (STYLENS,u'leader-color'), + (STYLENS,u'position'), + (STYLENS,u'leader-text'), + (STYLENS,u'type'), + (STYLENS,u'leader-type'), + ), + (STYLENS,u'tab-stops'):( + ), + (STYLENS,u'table-cell-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'cell-protect'), + (STYLENS,u'decimal-places'), + (STYLENS,u'diagonal-bl-tr'), + (STYLENS,u'diagonal-bl-tr-widths'), + (STYLENS,u'diagonal-tl-br'), + (STYLENS,u'diagonal-tl-br-widths'), + (STYLENS,u'direction'), + (STYLENS,u'glyph-orientation-vertical'), + (STYLENS,u'print-content'), + (STYLENS,u'repeat-content'), + (STYLENS,u'rotation-align'), + (STYLENS,u'rotation-angle'), + (STYLENS,u'shadow'), + (STYLENS,u'shrink-to-fit'), + (STYLENS,u'text-align-source'), + (STYLENS,u'vertical-align'), + ), + (STYLENS,u'table-column-properties'): ( + (FONS,u'break-after'), + (FONS,u'break-before'), + (STYLENS,u'column-width'), + (STYLENS,u'rel-column-width'), + (STYLENS,u'use-optimal-column-width'), + ), + (STYLENS,u'table-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-with-next'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (STYLENS,u'may-break-between-rows'), + (STYLENS,u'page-number'), + (STYLENS,u'rel-width'), + (STYLENS,u'shadow'), + (STYLENS,u'width'), + (STYLENS,u'writing-mode'), + (TABLENS,u'align'), + (TABLENS,u'border-model'), + (TABLENS,u'display'), + ), + (STYLENS,u'table-row-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-together'), + (STYLENS,u'min-row-height'), + (STYLENS,u'row-height'), + (STYLENS,u'use-optimal-row-height'), + ), +# allowed_attributes + (STYLENS,u'text-properties'): ( + (FONS,u'background-color'), + (FONS,u'color'), + (FONS,u'country'), + (FONS,u'font-family'), + (FONS,u'font-size'), + (FONS,u'font-style'), + (FONS,u'font-variant'), + (FONS,u'font-weight'), + (FONS,u'hyphenate'), + (FONS,u'hyphenation-push-char-count'), + (FONS,u'hyphenation-remain-char-count'), + (FONS,u'language'), + (FONS,u'letter-spacing'), + (FONS,u'text-shadow'), + (FONS,u'text-transform'), + (STYLENS,u'country-asian'), + (STYLENS,u'country-complex'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-family-asian'), + (STYLENS,u'font-family-complex'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-family-generic-asian'), + (STYLENS,u'font-family-generic-complex'), + (STYLENS,u'font-name'), + (STYLENS,u'font-name-asian'), + (STYLENS,u'font-name-complex'), + (STYLENS,u'font-pitch'), + (STYLENS,u'font-pitch-asian'), + (STYLENS,u'font-pitch-complex'), + (STYLENS,u'font-relief'), + (STYLENS,u'font-size-asian'), + (STYLENS,u'font-size-complex'), + (STYLENS,u'font-size-rel'), + (STYLENS,u'font-size-rel-asian'), + (STYLENS,u'font-size-rel-complex'), + (STYLENS,u'font-style-asian'), + (STYLENS,u'font-style-complex'), + (STYLENS,u'font-style-name'), + (STYLENS,u'font-style-name-asian'), + (STYLENS,u'font-style-name-complex'), + (STYLENS,u'font-weight-asian'), + (STYLENS,u'font-weight-complex'), + (STYLENS,u'language-asian'), + (STYLENS,u'language-complex'), + (STYLENS,u'letter-kerning'), + (STYLENS,u'script-type'), + (STYLENS,u'text-blinking'), + (STYLENS,u'text-combine'), + (STYLENS,u'text-combine-end-char'), + (STYLENS,u'text-combine-start-char'), + (STYLENS,u'text-emphasize'), + (STYLENS,u'text-line-through-color'), + (STYLENS,u'text-line-through-mode'), + (STYLENS,u'text-line-through-style'), + (STYLENS,u'text-line-through-text'), + (STYLENS,u'text-line-through-text-style'), + (STYLENS,u'text-line-through-type'), + (STYLENS,u'text-line-through-width'), + (STYLENS,u'text-outline'), + (STYLENS,u'text-position'), + (STYLENS,u'text-rotation-angle'), + (STYLENS,u'text-rotation-scale'), + (STYLENS,u'text-scale'), + (STYLENS,u'text-underline-color'), + (STYLENS,u'text-underline-mode'), + (STYLENS,u'text-underline-style'), + (STYLENS,u'text-underline-type'), + (STYLENS,u'text-underline-width'), + (STYLENS,u'use-window-font-color'), + (TEXTNS,u'condition'), + (TEXTNS,u'display'), + ), + (SVGNS,u'definition-src'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'desc'):( + ), + (SVGNS,u'font-face-format'):( + (SVGNS,u'string'), + ), + (SVGNS,u'font-face-name'):( + (SVGNS,u'name'), + ), + (SVGNS,u'font-face-src'):( + ), + (SVGNS,u'font-face-uri'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'linearGradient'):( + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'x2'), + (SVGNS,u'gradientTransform'), + (SVGNS,u'y1'), + (DRAWNS,u'display-name'), + (SVGNS,u'x1'), + ), + (SVGNS,u'radialGradient'):( + (DRAWNS,u'name'), + (SVGNS,u'fx'), + (SVGNS,u'fy'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'gradientTransform'), + (DRAWNS,u'display-name'), + (SVGNS,u'r'), + ), + (SVGNS,u'stop'):( + (SVGNS,u'stop-color'), + (SVGNS,u'stop-opacity'), + (SVGNS,u'offset'), + ), + (TABLENS,u'body'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'calculation-settings'):( + (TABLENS,u'automatic-find-labels'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'search-criteria-must-apply-to-whole-cell'), + (TABLENS,u'precision-as-shown'), + (TABLENS,u'use-regular-expressions'), + (TABLENS,u'null-year'), + ), + (TABLENS,u'cell-address'):( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), + (TABLENS,u'cell-content-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'):( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (TABLENS,u'name'), + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'refresh-delay'), + (XLINKNS,u'type'), + ), + (TABLENS,u'change-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'change-track-table-cell'):( + (OFFICENS,u'string-value'), + (TABLENS,u'cell-address'), + (TABLENS,u'number-matrix-columns-spanned'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'matrix-covered'), + (OFFICENS,u'value-type'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'consolidation'):( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + (TABLENS,u'link-to-source-data'), + (TABLENS,u'use-labels'), + ), + (TABLENS,u'content-validation'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'display-list'), + (TABLENS,u'allow-empty-cell'), + (TABLENS,u'name'), + (TABLENS,u'condition'), + ), + (TABLENS,u'content-validations'):( + ), + (TABLENS,u'covered-table-cell'):( + (TABLENS,u'protect'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (TABLENS,u'style-name'), + (TABLENS,u'content-validation-name'), + (OFFICENS,u'value-type'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'cut-offs'):( + ), + (TABLENS,u'data-pilot-display-info'):( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), + (TABLENS,u'data-pilot-field'):( + (TABLENS,u'selected-page'), + (TABLENS,u'function'), + (TABLENS,u'orientation'), + (TABLENS,u'used-hierarchy'), + (TABLENS,u'is-data-layout-field'), + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'):( + (TABLENS,u'member-name'), + (TABLENS,u'field-name'), + (TABLENS,u'member-type'), + (TABLENS,u'type'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-group'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'):( + (TABLENS,u'date-end'), + (TABLENS,u'end'), + (TABLENS,u'start'), + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'date-start'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'):( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-level'):( + (TABLENS,u'show-empty'), + ), + (TABLENS,u'data-pilot-member'):( + (TABLENS,u'show-details'), + (TABLENS,u'name'), + (TABLENS,u'display'), + ), + (TABLENS,u'data-pilot-members'):( + ), + (TABLENS,u'data-pilot-sort-info'):( + (TABLENS,u'data-field'), + (TABLENS,u'sort-mode'), + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'):( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-subtotals'):( + ), + (TABLENS,u'data-pilot-table'):( + (TABLENS,u'buttons'), + (TABLENS,u'application-data'), + (TABLENS,u'name'), + (TABLENS,u'drill-down-on-double-click'), + (TABLENS,u'target-range-address'), + (TABLENS,u'ignore-empty-rows'), + (TABLENS,u'identify-categories'), + (TABLENS,u'show-filter-button'), + (TABLENS,u'grand-total'), + ), + (TABLENS,u'data-pilot-tables'):( + ), + (TABLENS,u'database-range'):( + (TABLENS,u'orientation'), + (TABLENS,u'target-range-address'), + (TABLENS,u'contains-header'), + (TABLENS,u'on-update-keep-size'), + (TABLENS,u'name'), + (TABLENS,u'is-selection'), + (TABLENS,u'refresh-delay'), + (TABLENS,u'display-filter-buttons'), + (TABLENS,u'has-persistent-data'), + (TABLENS,u'on-update-keep-styles'), + ), + (TABLENS,u'database-ranges'):( + ), + (TABLENS,u'database-source-query'):( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'database-source-sql'):( + (TABLENS,u'parse-sql-statement'), + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'):( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'dde-link'):( + ), + (TABLENS,u'dde-links'):( + ), + (TABLENS,u'deletion'):( + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'multi-deletion-spanned'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'deletions'):( + ), + (TABLENS,u'dependencies'):( + ), + (TABLENS,u'dependency'):( + (TABLENS,u'id'), + ), + (TABLENS,u'detective'):( + ), + (TABLENS,u'error-macro'):( + (TABLENS,u'execute'), + ), + (TABLENS,u'error-message'):( + (TABLENS,u'display'), + (TABLENS,u'message-type'), + (TABLENS,u'title'), + ), + (TABLENS,u'even-columns'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'even-rows'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'filter'):( + (TABLENS,u'target-range-address'), + (TABLENS,u'display-duplicates'), + (TABLENS,u'condition-source-range-address'), + (TABLENS,u'condition-source'), + ), + (TABLENS,u'filter-and'):( + ), + (TABLENS,u'filter-condition'):( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'value'), + ), + (TABLENS,u'filter-or'):( + ), + (TABLENS,u'first-column'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'first-row'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'help-message'):( + (TABLENS,u'display'), + (TABLENS,u'title'), + ), + (TABLENS,u'highlighted-range'):( + (TABLENS,u'contains-error'), + (TABLENS,u'direction'), + (TABLENS,u'marked-invalid'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'insertion'):( + (TABLENS,u'count'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), + (TABLENS,u'iteration'):( + (TABLENS,u'status'), + (TABLENS,u'maximum-difference'), + (TABLENS,u'steps'), + ), +# allowed_attributes + (TABLENS,u'label-range'):( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'label-ranges'):( + ), + (TABLENS,u'last-column'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'last-row'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'movement'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), + (TABLENS,u'movement-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'end-position'), + (TABLENS,u'start-position'), + ), + (TABLENS,u'named-expression'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-expressions'):( + ), + (TABLENS,u'named-range'):( + (TABLENS,u'range-usable-as'), + (TABLENS,u'base-cell-address'), + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'null-date'):( + (TABLENS,u'date-value-type'), + (TABLENS,u'value-type'), + ), + (TABLENS,u'odd-columns'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'odd-rows'):( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'operation'):( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), + (TABLENS,u'previous'):( + (TABLENS,u'id'), + ), + (TABLENS,u'scenario'):( + (TABLENS,u'comment'), + (TABLENS,u'border-color'), + (TABLENS,u'copy-back'), + (TABLENS,u'is-active'), + (TABLENS,u'protected'), + (TABLENS,u'copy-formulas'), + (TABLENS,u'copy-styles'), + (TABLENS,u'scenario-ranges'), + (TABLENS,u'display-border'), + ), + (TABLENS,u'shapes'):( + ), + (TABLENS,u'sort'):( + (TABLENS,u'case-sensitive'), + (TABLENS,u'algorithm'), + (TABLENS,u'target-range-address'), + (TABLENS,u'country'), + (TABLENS,u'language'), + (TABLENS,u'bind-styles-to-content'), + ), + (TABLENS,u'sort-by'):( + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'sort-groups'):( + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'source-cell-range'):( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), + (TABLENS,u'source-service'):( + (TABLENS,u'user-name'), + (TABLENS,u'source-name'), + (TABLENS,u'password'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'):( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'):( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'subtotal-rules'):( + (TABLENS,u'bind-styles-to-content'), + (TABLENS,u'page-breaks-on-group-change'), + (TABLENS,u'case-sensitive'), + ), + (TABLENS,u'table'):( + (TABLENS,u'name'), + (TABLENS,u'is-sub-table'), + (TABLENS,u'style-name'), + (TABLENS,u'protected'), + (TABLENS,u'print-ranges'), + (TABLENS,u'print'), + (TABLENS,u'protection-key'), + ), + (TABLENS,u'table-cell'):( + (TABLENS,u'protect'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'number-matrix-columns-spanned'), + (OFFICENS,u'string-value'), + (TABLENS,u'number-columns-spanned'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (TABLENS,u'style-name'), + (TABLENS,u'content-validation-name'), + (OFFICENS,u'value-type'), + (TABLENS,u'number-rows-spanned'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'table-column'):( + (TABLENS,u'style-name'), + (TABLENS,u'default-cell-style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'number-columns-repeated'), + ), + (TABLENS,u'table-column-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-columns'):( + ), + (TABLENS,u'table-header-columns'):( + ), + (TABLENS,u'table-header-rows'):( + ), + (TABLENS,u'table-row'):( + (TABLENS,u'number-rows-repeated'), + (TABLENS,u'style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'default-cell-style-name'), + ), + (TABLENS,u'table-row-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-rows'):( + ), + (TABLENS,u'table-source'):( + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'mode'), + (TABLENS,u'table-name'), + (XLINKNS,u'type'), + (TABLENS,u'refresh-delay'), + ), + (TABLENS,u'table-template'):( + (TEXTNS,u'last-row-end-column'), + (TEXTNS,u'first-row-end-column'), + (TEXTNS,u'name'), + (TEXTNS,u'last-row-start-column'), + (TEXTNS,u'first-row-start-column'), + ), + (TABLENS,u'target-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), + (TABLENS,u'tracked-changes'):( + (TABLENS,u'track-changes'), + ), +# allowed_attributes + (TEXTNS,u'a'):( + (TEXTNS,u'visited-style-name'), + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'actuate'), + (TEXTNS,u'style-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'string-value-phonetic'), + ), + (TEXTNS,u'alphabetical-index-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value-phonetic'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-source'):( + (TEXTNS,u'capitalize-entries'), + (FONS,u'language'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'alphabetical-separators'), + (TEXTNS,u'combine-entries-with-pp'), + (TEXTNS,u'combine-entries-with-dash'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'ignore-case'), + (TEXTNS,u'combine-entries'), + (TEXTNS,u'comma-separated'), + (FONS,u'country'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'main-entry-style-name'), + (TEXTNS,u'use-keys-as-entries'), + ), +# allowed_attributes + (TEXTNS,u'author-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'author-name'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'bibliography'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'bibliography-configuration'):( + (TEXTNS,u'suffix'), + (FONS,u'language'), + (TEXTNS,u'numbered-entries'), + (FONS,u'country'), + (TEXTNS,u'sort-by-position'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'prefix'), + ), + (TEXTNS,u'bibliography-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bibliography-mark'):( + (TEXTNS,u'address'), + (TEXTNS,u'annote'), + (TEXTNS,u'author'), + (TEXTNS,u'bibliography-type'), + (TEXTNS,u'booktitle'), + (TEXTNS,u'chapter'), + (TEXTNS,u'custom1'), + (TEXTNS,u'custom2'), + (TEXTNS,u'custom3'), + (TEXTNS,u'custom4'), + (TEXTNS,u'custom5'), + (TEXTNS,u'edition'), + (TEXTNS,u'editor'), + (TEXTNS,u'howpublished'), + (TEXTNS,u'identifier'), + (TEXTNS,u'institution'), + (TEXTNS,u'isbn'), + (TEXTNS,u'issn'), + (TEXTNS,u'journal'), + (TEXTNS,u'month'), + (TEXTNS,u'note'), + (TEXTNS,u'number'), + (TEXTNS,u'organizations'), + (TEXTNS,u'pages'), + (TEXTNS,u'publisher'), + (TEXTNS,u'report-type'), + (TEXTNS,u'school'), + (TEXTNS,u'series'), + (TEXTNS,u'title'), + (TEXTNS,u'url'), + (TEXTNS,u'volume'), + (TEXTNS,u'year'), + ), + (TEXTNS,u'bibliography-source'):( + ), + (TEXTNS,u'bookmark'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'bookmark-start'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'change'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'chapter'):( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'):( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'current-value'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'creation-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creation-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'database-display'):( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'database-name'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + ), + (TEXTNS,u'database-next'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-row-number'):( + (STYLENS,u'num-format'), + (TEXTNS,u'database-name'), + (TEXTNS,u'value'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + ), + (TEXTNS,u'database-row-select'):( + (TEXTNS,u'row-number'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), +# allowed_attributes + (TEXTNS,u'date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (TEXTNS,u'date-adjust'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'dde-connection'):( + (TEXTNS,u'connection-name'), + ), + (TEXTNS,u'dde-connection-decl'):( + (OFFICENS,u'automatic-update'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'dde-connection-decls'):( + ), + (TEXTNS,u'deletion'):( + ), + (TEXTNS,u'description'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-cycles'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-duration'):( + (TEXTNS,u'duration'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'execute-macro'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'expression'):( + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'file-name'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'format-change'):( + ), + (TEXTNS,u'h'):( + (TEXTNS,u'restart-numbering'), + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'is-list-header'), + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + (TEXTNS,u'start-value'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'hidden-paragraph'):( + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'illustration-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'illustration-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), + (TEXTNS,u'index-body'):( + ), + (TEXTNS,u'index-entry-bibliography'):( + (TEXTNS,u'bibliography-data-field'), + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-chapter'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'index-entry-link-end'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-link-start'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-page-number'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-span'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-tab-stop'):( + (STYLENS,u'position'), + (TEXTNS,u'style-name'), + (STYLENS,u'type'), + (STYLENS,u'leader-char'), + ), + (TEXTNS,u'index-entry-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-style'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'):( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'index-title-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'initial-creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'insertion'):( + ), +# allowed_attributes + (TEXTNS,u'keywords'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'line-break'):( + ), + (TEXTNS,u'linenumbering-configuration'):( + (TEXTNS,u'number-position'), + (TEXTNS,u'number-lines'), + (STYLENS,u'num-format'), + (TEXTNS,u'count-empty-lines'), + (TEXTNS,u'count-in-text-boxes'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'increment'), + (TEXTNS,u'offset'), + (TEXTNS,u'restart-on-page'), + ), + (TEXTNS,u'linenumbering-separator'):( + (TEXTNS,u'increment'), + ), + (TEXTNS,u'list'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'continue-numbering'), + ), + (TEXTNS,u'list-header'):( + ), + (TEXTNS,u'list-item'):( + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'list-level-style-bullet'):( + (TEXTNS,u'level'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'bullet-relative-size'), + (TEXTNS,u'style-name'), + (TEXTNS,u'bullet-char'), + ), + (TEXTNS,u'list-level-style-image'):( + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'list-style'):( + (TEXTNS,u'consecutive-numbering'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), + (TEXTNS,u'measure'):( + (TEXTNS,u'kind'), + ), + (TEXTNS,u'modification-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'modification-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'note'):( + (TEXTNS,u'note-class'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'note-body'):( + ), + (TEXTNS,u'note-citation'):( + (TEXTNS,u'label'), + ), + (TEXTNS,u'note-continuation-notice-backward'):( + ), + (TEXTNS,u'note-continuation-notice-forward'):( + ), + (TEXTNS,u'note-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'note-class'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'notes-configuration'):( + (TEXTNS,u'citation-body-style-name'), + (STYLENS,u'num-format'), + (TEXTNS,u'default-style-name'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'start-numbering-at'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'citation-style-name'), + (TEXTNS,u'footnotes-position'), + (TEXTNS,u'master-page-name'), + (TEXTNS,u'start-value'), + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'number'):( + ), + (TEXTNS,u'numbered-paragraph'):( + (TEXTNS,u'continue-numbering'), + (TEXTNS,u'style-name'), + (TEXTNS,u'start-value'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'object-count'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'object-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), +# allowed_attributes + (TEXTNS,u'object-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'object-index-source'):( + (TEXTNS,u'use-draw-objects'), + (TEXTNS,u'use-math-objects'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-chart-objects'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'use-spreadsheet-objects'), + (TEXTNS,u'use-other-objects'), + ), + (TEXTNS,u'outline-level-style'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'outline-style'):( + ), + (TEXTNS,u'p'):( + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'page'):( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-number'):( + (TEXTNS,u'page-adjust'), + (STYLENS,u'num-format'), + (TEXTNS,u'fixed'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-sequence'):( + ), + (TEXTNS,u'page-variable-get'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'page-variable-set'):( + (TEXTNS,u'active'), + (TEXTNS,u'page-adjust'), + ), + (TEXTNS,u'placeholder'):( + (TEXTNS,u'placeholder-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'print-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'print-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'printed-by'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'reference-mark'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'ruby'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'ruby-base'):( + ), + (TEXTNS,u'ruby-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u's'):( + (TEXTNS,u'c'), + ), + (TEXTNS,u'script'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (SCRIPTNS,u'language'), + ), + (TEXTNS,u'section'):( + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'style-name'), + (TEXTNS,u'protected'), + (TEXTNS,u'display'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'section-source'):( + (TEXTNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'section-name'), + (XLINKNS,u'show'), + ), + (TEXTNS,u'sender-city'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-company'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-country'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-email'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-fax'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-firstname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-lastname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-private'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-work'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-position'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-postal-code'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-state-or-province'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-street'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sequence'):( + (TEXTNS,u'formula'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'name'), + (TEXTNS,u'ref-name'), + ), + (TEXTNS,u'sequence-decl'):( + (TEXTNS,u'separation-character'), + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decls'):( + ), + (TEXTNS,u'sequence-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'sheet-name'):( + ), + (TEXTNS,u'sort-key'):( + (TEXTNS,u'sort-ascending'), + (TEXTNS,u'key'), + ), +# allowed_attributes + (TEXTNS,u'span'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + ), + (TEXTNS,u'subject'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'tab'):( + (TEXTNS,u'tab-ref'), + ), + (TEXTNS,u'table-formula'):( + (TEXTNS,u'formula'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'table-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'table-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), + (TEXTNS,u'table-of-content'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'table-of-content-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'table-of-content-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'outline-level'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-outline-level'), + (TEXTNS,u'use-index-source-styles'), + ), + (TEXTNS,u'template-name'):( + (TEXTNS,u'display'), + ), + (TEXTNS,u'text-input'):( + (TEXTNS,u'description'), + ), + (TEXTNS,u'time'):( + (TEXTNS,u'time-adjust'), + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'toc-mark'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'):( + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'tracked-changes'):( + (TEXTNS,u'track-changes'), + ), + (TEXTNS,u'user-defined'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'fixed'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decls'):( + ), + (TEXTNS,u'user-field-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'user-field-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'user-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'user-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark-end'):( + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark-start'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), +# allowed_attributes + (TEXTNS,u'user-index-source'):( + (TEXTNS,u'copy-outline-levels'), + (TEXTNS,u'index-name'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-floating-frames'), + (TEXTNS,u'use-graphics'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-objects'), + (TEXTNS,u'use-tables'), + ), + (TEXTNS,u'variable-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-decls'):( + ), + (TEXTNS,u'variable-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'variable-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'variable-set'):( + (TEXTNS,u'name'), + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), +# allowed_attributes +} diff --git a/src/odf/load.py b/src/odf/load.py new file mode 100644 index 0000000000..a2b6b744c2 --- /dev/null +++ b/src/odf/load.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +# This script is to be embedded in opendocument.py later +# The purpose is to read an ODT/ODP/ODS file and create the datastructure +# in memory. The user should then be able to make operations and then save +# the structure again. + +from xml.sax import make_parser,handler +from xml.sax.xmlreader import InputSource +import xml.sax.saxutils +from element import Element +from namespaces import OFFICENS + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + + +# +# Parse the XML files +# +class LoadParser(handler.ContentHandler): + """ Extract headings from content.xml of an ODT file """ + triggers = ( + (OFFICENS, 'automatic-styles'), (OFFICENS, 'body'), + (OFFICENS, 'font-face-decls'), (OFFICENS, 'master-styles'), + (OFFICENS, 'meta'), (OFFICENS, 'scripts'), + (OFFICENS, 'settings'), (OFFICENS, 'styles') ) + + def __init__(self, document): + self.doc = document + self.data = [] + self.level = 0 + self.parse = False + + def characters(self, data): + if self.parse == False: + return + self.data.append(data) + + def startElementNS(self, tag, qname, attrs): + if tag in self.triggers: + self.parse = True + if self.doc._parsing != "styles.xml" and tag == (OFFICENS, 'font-face-decls'): + self.parse = False + if self.parse == False: + return + + self.level = self.level + 1 + # Add any accumulated text content + content = ''.join(self.data).strip() + if len(content) > 0: + self.parent.addText(content) + self.data = [] + # Create the element + attrdict = {} + for (att,value) in attrs.items(): + attrdict[att] = value + try: + e = Element(qname = tag, qattributes=attrdict, check_grammar=False) + self.curr = e + except AttributeError, v: + print "Error: %s" % v + + if tag == (OFFICENS, 'automatic-styles'): + e = self.doc.automaticstyles + elif tag == (OFFICENS, 'body'): + e = self.doc.body + elif tag == (OFFICENS, 'master-styles'): + e = self.doc.masterstyles + elif tag == (OFFICENS, 'meta'): + e = self.doc.meta + elif tag == (OFFICENS,'scripts'): + e = self.doc.scripts + elif tag == (OFFICENS,'settings'): + e = self.doc.settings + elif tag == (OFFICENS,'styles'): + e = self.doc.styles + elif self.doc._parsing == "styles.xml" and tag == (OFFICENS, 'font-face-decls'): + e = self.doc.fontfacedecls + elif hasattr(self,'parent'): + self.parent.addElement(e, check_grammar=False) + self.parent = e + + + def endElementNS(self, tag, qname): + if self.parse == False: + return + self.level = self.level - 1 + str = ''.join(self.data) + if len(str.strip()) > 0: + self.curr.addText(str) + self.data = [] + self.curr = self.curr.parentNode + self.parent = self.curr + if tag in self.triggers: + self.parse = False diff --git a/src/odf/manifest.py b/src/odf/manifest.py new file mode 100644 index 0000000000..5a845335e4 --- /dev/null +++ b/src/odf/manifest.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +# + +from namespaces import MANIFESTNS +from element import Element + +# Autogenerated +def Manifest(**args): + return Element(qname = (MANIFESTNS,'manifest'), **args) + +def FileEntry(**args): + return Element(qname = (MANIFESTNS,'file-entry'), **args) + +def EncryptionData(**args): + return Element(qname = (MANIFESTNS,'encryption-data'), **args) + +def Algorithm(**args): + return Element(qname = (MANIFESTNS,'algorithm'), **args) + +def KeyDerivation(**args): + return Element(qname = (MANIFESTNS,'key-derivation'), **args) + + + +if __name__ == "__main__": + import cStringIO + xml=cStringIO.StringIO() + m = Manifest() + f = FileEntry(mediatype="text/xml", fullpath="content.xml") + m.addElement(f) + + m.toXml(0,xml) + print xml.getvalue() + diff --git a/src/odf/math.py b/src/odf/math.py new file mode 100644 index 0000000000..5dc38dfad3 --- /dev/null +++ b/src/odf/math.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import MATHNS +from element import Element + +# ODF 1.0 section 12.5 +# Mathematical content is represented by MathML 2.0 + +# Autogenerated +def Math(**args): + return Element(qname = (MATHNS,'math'), **args) + diff --git a/src/odf/meta.py b/src/odf/meta.py new file mode 100644 index 0000000000..dc0318117a --- /dev/null +++ b/src/odf/meta.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import METANS +from element import Element + +# Autogenerated +def AutoReload(**args): + return Element(qname = (METANS,'auto-reload'), **args) + +def CreationDate(**args): + return Element(qname = (METANS,'creation-date'), **args) + +def DateString(**args): + return Element(qname = (METANS,'date-string'), **args) + +def DocumentStatistic(**args): + return Element(qname = (METANS,'document-statistic'), **args) + +def EditingCycles(**args): + return Element(qname = (METANS,'editing-cycles'), **args) + +def EditingDuration(**args): + return Element(qname = (METANS,'editing-duration'), **args) + +def Generator(**args): + return Element(qname = (METANS,'generator'), **args) + +def HyperlinkBehaviour(**args): + return Element(qname = (METANS,'hyperlink-behaviour'), **args) + +def InitialCreator(**args): + return Element(qname = (METANS,'initial-creator'), **args) + +def Keyword(**args): + return Element(qname = (METANS,'keyword'), **args) + +def PrintDate(**args): + return Element(qname = (METANS,'print-date'), **args) + +def PrintedBy(**args): + return Element(qname = (METANS,'printed-by'), **args) + +def Template(**args): + return Element(qname = (METANS,'template'), **args) + +def UserDefined(**args): + return Element(qname = (METANS,'user-defined'), **args) + diff --git a/src/odf/namespaces.py b/src/odf/namespaces.py new file mode 100644 index 0000000000..912d82d46b --- /dev/null +++ b/src/odf/namespaces.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +TOOLSVERSION = u"ODFPY/0.8.1dev" + +ANIMNS = u"urn:oasis:names:tc:opendocument:xmlns:animation:1.0" +CHARTNS = u"urn:oasis:names:tc:opendocument:xmlns:chart:1.0" +CONFIGNS = u"urn:oasis:names:tc:opendocument:xmlns:config:1.0" +DBNS = u"http://openoffice.org/2004/database" +DCNS = u"http://purl.org/dc/elements/1.1/" +DOMNS = u"http://www.w3.org/2001/xml-events" +DR3DNS = u"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" +DRAWNS = u"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" +FONS = u"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +FORMNS = u"urn:oasis:names:tc:opendocument:xmlns:form:1.0" +KOFFICENS = u"http://www.koffice.org/2005/" +MANIFESTNS = u"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" +MATHNS = u"http://www.w3.org/1998/Math/MathML" +METANS = u"urn:oasis:names:tc:opendocument:xmlns:meta:1.0" +NUMBERNS = u"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" +OFFICENS = u"urn:oasis:names:tc:opendocument:xmlns:office:1.0" +OOONS = u"http://openoffice.org/2004/office" +OOOWNS = u"http://openoffice.org/2004/writer" +OOOCNS = u"http://openoffice.org/2004/calc" +PRESENTATIONNS = u"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" +SCRIPTNS = u"urn:oasis:names:tc:opendocument:xmlns:script:1.0" +SMILNS = u"urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" +STYLENS = u"urn:oasis:names:tc:opendocument:xmlns:style:1.0" +SVGNS = u"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" +TABLENS = u"urn:oasis:names:tc:opendocument:xmlns:table:1.0" +TEXTNS = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0" +XFORMSNS = u"http://www.w3.org/2002/xforms" +XLINKNS = u"http://www.w3.org/1999/xlink" + + +nsdict = { + ANIMNS: u'anim', + CHARTNS: u'chart', + CONFIGNS: u'config', + DBNS: u'db', + DCNS: u'dc', + DOMNS: u'dom', + DR3DNS: u'dr3d', + DRAWNS: u'draw', + FONS: u'fo', + FORMNS: u'form', + KOFFICENS: u'koffice', + MANIFESTNS: u'manifest', + MATHNS: u'math', + METANS: u'meta', + NUMBERNS: u'number', + OFFICENS: u'office', + OOONS: u'ooo', + OOOWNS: u'ooow', + OOOCNS: u'ooc', + PRESENTATIONNS: u'presentation', + SCRIPTNS: u'script', + SMILNS: u'smil', + STYLENS: u'style', + SVGNS: u'svg', + TABLENS: u'table', + TEXTNS: u'text', + XFORMSNS: u'xforms', + XLINKNS: u'xlink', +} diff --git a/src/odf/number.py b/src/odf/number.py new file mode 100644 index 0000000000..12d81cba16 --- /dev/null +++ b/src/odf/number.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import NUMBERNS +from element import Element +from style import StyleElement + + +# Autogenerated +def AmPm(**args): + return Element(qname = (NUMBERNS,'am-pm'), **args) + +def Boolean(**args): + return Element(qname = (NUMBERNS,'boolean'), **args) + +def BooleanStyle(**args): + return StyleElement(qname = (NUMBERNS,'boolean-style'), **args) + +def CurrencyStyle(**args): + return StyleElement(qname = (NUMBERNS,'currency-style'), **args) + +def CurrencySymbol(**args): + return Element(qname = (NUMBERNS,'currency-symbol'), **args) + +def DateStyle(**args): + return StyleElement(qname = (NUMBERNS,'date-style'), **args) + +def Day(**args): + return Element(qname = (NUMBERNS,'day'), **args) + +def DayOfWeek(**args): + return Element(qname = (NUMBERNS,'day-of-week'), **args) + +def EmbeddedText(**args): + return Element(qname = (NUMBERNS,'embedded-text'), **args) + +def Era(**args): + return Element(qname = (NUMBERNS,'era'), **args) + +def Fraction(**args): + return Element(qname = (NUMBERNS,'fraction'), **args) + +def Hours(**args): + return Element(qname = (NUMBERNS,'hours'), **args) + +def Minutes(**args): + return Element(qname = (NUMBERNS,'minutes'), **args) + +def Month(**args): + return Element(qname = (NUMBERNS,'month'), **args) + +def Number(**args): + return Element(qname = (NUMBERNS,'number'), **args) + +def NumberStyle(**args): + return StyleElement(qname = (NUMBERNS,'number-style'), **args) + +def PercentageStyle(**args): + return StyleElement(qname = (NUMBERNS,'percentage-style'), **args) + +def Quarter(**args): + return Element(qname = (NUMBERNS,'quarter'), **args) + +def ScientificNumber(**args): + return Element(qname = (NUMBERNS,'scientific-number'), **args) + +def Seconds(**args): + return Element(qname = (NUMBERNS,'seconds'), **args) + +def Text(**args): + return Element(qname = (NUMBERNS,'text'), **args) + +def TextContent(**args): + return Element(qname = (NUMBERNS,'text-content'), **args) + +def TextStyle(**args): + return StyleElement(qname = (NUMBERNS,'text-style'), **args) + +def TimeStyle(**args): + return StyleElement(qname = (NUMBERNS,'time-style'), **args) + +def WeekOfYear(**args): + return Element(qname = (NUMBERNS,'week-of-year'), **args) + +def Year(**args): + return Element(qname = (NUMBERNS,'year'), **args) + diff --git a/src/odf/odf2moinmoin.py b/src/odf/odf2moinmoin.py new file mode 100644 index 0000000000..167fcdacb5 --- /dev/null +++ b/src/odf/odf2moinmoin.py @@ -0,0 +1,579 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# See http://trac.edgewall.org/wiki/WikiFormatting +# +# Contributor(s): +# + +import sys, zipfile, xml.dom.minidom +from namespaces import nsdict +from elementtypes import * + +IGNORED_TAGS = [ + 'draw:a' + 'draw:g', + 'draw:line', + 'draw:object-ole', + 'office:annotation', + 'presentation:notes', + 'svg:desc', +] + [ nsdict[item[0]]+":"+item[1] for item in empty_elements] + +INLINE_TAGS = [ nsdict[item[0]]+":"+item[1] for item in inline_elements] + + +class TextProps: + """ Holds properties for a text style. """ + + def __init__(self): + + self.italic = False + self.bold = False + self.fixed = False + self.underlined = False + self.strikethrough = False + self.superscript = False + self.subscript = False + + def setItalic(self, value): + if value == "italic": + self.italic = True + elif value == "normal": + self.italic = False + + def setBold(self, value): + if value == "bold": + self.bold = True + elif value == "normal": + self.bold = False + + def setFixed(self, value): + self.fixed = value + + def setUnderlined(self, value): + if value and value != "none": + self.underlined = True + + def setStrikethrough(self, value): + if value and value != "none": + self.strikethrough = True + + def setPosition(self, value): + if value is None or value == '': + return + posisize = value.split(' ') + textpos = posisize[0] + if textpos.find('%') == -1: + if textpos == "sub": + self.superscript = False + self.subscript = True + elif textpos == "super": + self.superscript = True + self.subscript = False + else: + itextpos = int(textpos[:textpos.find('%')]) + if itextpos > 10: + self.superscript = False + self.subscript = True + elif itextpos < -10: + self.superscript = True + self.subscript = False + + def __str__(self): + + return "[italic=%s, bold=i%s, fixed=%s]" % (str(self.italic), + str(self.bold), + str(self.fixed)) + +class ParagraphProps: + """ Holds properties of a paragraph style. """ + + def __init__(self): + + self.blockquote = False + self.headingLevel = 0 + self.code = False + self.title = False + self.indented = 0 + + def setIndented(self, value): + self.indented = value + + def setHeading(self, level): + self.headingLevel = level + + def setTitle(self, value): + self.title = value + + def setCode(self, value): + self.code = value + + + def __str__(self): + + return "[bq=%s, h=%d, code=%s]" % (str(self.blockquote), + self.headingLevel, + str(self.code)) + + +class ListProperties: + """ Holds properties for a list style. """ + + def __init__(self): + self.ordered = False + + def setOrdered(self, value): + self.ordered = value + + + +class ODF2MoinMoin(object): + + + def __init__(self, filepath): + self.footnotes = [] + self.footnoteCounter = 0 + self.textStyles = {"Standard": TextProps()} + self.paragraphStyles = {"Standard": ParagraphProps()} + self.listStyles = {} + self.fixedFonts = [] + self.hasTitle = 0 + self.lastsegment = None + + # Tags + self.elements = { + 'draw:page': self.textToString, + 'draw:frame': self.textToString, + 'draw:image': self.draw_image, + 'draw:text-box': self.textToString, + 'text:a': self.text_a, + 'text:note': self.text_note, + } + for tag in IGNORED_TAGS: + self.elements[tag] = self.do_nothing + + for tag in INLINE_TAGS: + self.elements[tag] = self.inline_markup + self.elements['text:line-break'] = self.text_line_break + self.elements['text:s'] = self.text_s + self.elements['text:tab'] = self.text_tab + + self.load(filepath) + + def processFontDeclarations(self, fontDecl): + """ Extracts necessary font information from a font-declaration + element. + """ + for fontFace in fontDecl.getElementsByTagName("style:font-face"): + if fontFace.getAttribute("style:font-pitch") == "fixed": + self.fixedFonts.append(fontFace.getAttribute("style:name")) + + + + def extractTextProperties(self, style, parent=None): + """ Extracts text properties from a style element. """ + + textProps = TextProps() + + if parent: + parentProp = self.textStyles.get(parent, None) + if parentProp: + textProp = parentProp + + textPropEl = style.getElementsByTagName("style:text-properties") + if not textPropEl: return textProps + + textPropEl = textPropEl[0] + + textProps.setItalic(textPropEl.getAttribute("fo:font-style")) + textProps.setBold(textPropEl.getAttribute("fo:font-weight")) + textProps.setUnderlined(textPropEl.getAttribute("style:text-underline-style")) + textProps.setStrikethrough(textPropEl.getAttribute("style:text-line-through-style")) + textProps.setPosition(textPropEl.getAttribute("style:text-position")) + + if textPropEl.getAttribute("style:font-name") in self.fixedFonts: + textProps.setFixed(True) + + return textProps + + def extractParagraphProperties(self, style, parent=None): + """ Extracts paragraph properties from a style element. """ + + paraProps = ParagraphProps() + + name = style.getAttribute("style:name") + + if name.startswith("Heading_20_"): + level = name[11:] + try: + level = int(level) + paraProps.setHeading(level) + except: + level = 0 + + if name == "Title": + paraProps.setTitle(True) + + paraPropEl = style.getElementsByTagName("style:paragraph-properties") + if paraPropEl: + paraPropEl = paraPropEl[0] + leftMargin = paraPropEl.getAttribute("fo:margin-left") + if leftMargin: + try: + leftMargin = float(leftMargin[:-2]) + if leftMargin > 0.01: + paraProps.setIndented(True) + except: + pass + + textProps = self.extractTextProperties(style) + if textProps.fixed: + paraProps.setCode(True) + + return paraProps + + + def processStyles(self, styleElements): + """ Runs through "style" elements extracting necessary information. + """ + + for style in styleElements: + + name = style.getAttribute("style:name") + + if name == "Standard": continue + + family = style.getAttribute("style:family") + parent = style.getAttribute("style:parent-style-name") + + if family == "text": + self.textStyles[name] = self.extractTextProperties(style, parent) + + elif family == "paragraph": + self.paragraphStyles[name] = \ + self.extractParagraphProperties(style, parent) + self.textStyles[name] = self.extractTextProperties(style, parent) + + def processListStyles(self, listStyleElements): + + for style in listStyleElements: + name = style.getAttribute("style:name") + + prop = ListProperties() + if style.hasChildNodes(): + subitems = [el for el in style.childNodes + if el.nodeType == xml.dom.Node.ELEMENT_NODE + and el.tagName == "text:list-level-style-number"] + if len(subitems) > 0: + prop.setOrdered(True) + + self.listStyles[name] = prop + + + def load(self, filepath): + """ Loads an ODT file. """ + + zip = zipfile.ZipFile(filepath) + + styles_doc = xml.dom.minidom.parseString(zip.read("styles.xml")) + fontfacedecls = styles_doc.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + self.processStyles(styles_doc.getElementsByTagName("style:style")) + self.processListStyles(styles_doc.getElementsByTagName("text:list-style")) + + self.content = xml.dom.minidom.parseString(zip.read("content.xml")) + fontfacedecls = self.content.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + + self.processStyles(self.content.getElementsByTagName("style:style")) + self.processListStyles(self.content.getElementsByTagName("text:list-style")) + + def compressCodeBlocks(self, text): + """ Removes extra blank lines from code blocks. """ + + return text + lines = text.split("\n") + buffer = [] + numLines = len(lines) + for i in range(numLines): + + if (lines[i].strip() or i == numLines-1 or i == 0 or + not ( lines[i-1].startswith(" ") + and lines[i+1].startswith(" ") ) ): + buffer.append("\n" + lines[i]) + + return ''.join(buffer) + +#----------------------------------- + def do_nothing(self, node): + return '' + + def draw_image(self, node): + """ + """ + + link = node.getAttribute("xlink:href") + if link and link[:2] == './': # Indicates a sub-object, which isn't supported + return "%s\n" % link + if link and link[:9] == 'Pictures/': + link = link[9:] + return "[[Image(%s)]]\n" % link + + def text_a(self, node): + text = self.textToString(node) + link = node.getAttribute("xlink:href") + if link.strip() == text.strip(): + return "[%s] " % link.strip() + else: + return "[%s %s] " % (link.strip(), text.strip()) + + + def text_line_break(self, node): + return "[[BR]]" + + def text_note(self, node): + cite = (node.getElementsByTagName("text:note-citation")[0] + .childNodes[0].nodeValue) + body = (node.getElementsByTagName("text:note-body")[0] + .childNodes[0]) + self.footnotes.append((cite, self.textToString(body))) + return "^%s^" % cite + + def text_s(self, node): + try: + num = int(node.getAttribute("text:c")) + return " "*num + except: + return " " + + def text_tab(self, node): + return " " + + def inline_markup(self, node): + text = self.textToString(node) + + if not text.strip(): + return '' # don't apply styles to white space + + styleName = node.getAttribute("text:style-name") + style = self.textStyles.get(styleName, TextProps()) + + if style.fixed: + return "`" + text + "`" + + mark = [] + if style: + if style.italic: + mark.append("''") + if style.bold: + mark.append("'''") + if style.underlined: + mark.append("__") + if style.strikethrough: + mark.append("~~") + if style.superscript: + mark.append("^") + if style.subscript: + mark.append(",,") + revmark = mark[:] + revmark.reverse() + return "%s%s%s" % (''.join(mark), text, ''.join(revmark)) + +#----------------------------------- + def listToString(self, listElement, indent = 0): + + self.lastsegment = listElement.tagName + buffer = [] + + styleName = listElement.getAttribute("text:style-name") + props = self.listStyles.get(styleName, ListProperties()) + + i = 0 + for item in listElement.childNodes: + buffer.append(" "*indent) + i += 1 + if props.ordered: + number = str(i) + number = " " + number + ". " + buffer.append(" 1. ") + else: + buffer.append(" * ") + subitems = [el for el in item.childNodes + if el.tagName in ["text:p", "text:h", "text:list"]] + for subitem in subitems: + if subitem.tagName == "text:list": + buffer.append("\n") + buffer.append(self.listToString(subitem, indent+3)) + else: + buffer.append(self.paragraphToString(subitem, indent+3)) + self.lastsegment = subitem.tagName + self.lastsegment = item.tagName + buffer.append("\n") + + return ''.join(buffer) + + def tableToString(self, tableElement): + """ MoinMoin uses || to delimit table cells + """ + + self.lastsegment = tableElement.tagName + buffer = [] + + for item in tableElement.childNodes: + self.lastsegment = item.tagName + if item.tagName == "table:table-header-rows": + buffer.append(self.tableToString(item)) + if item.tagName == "table:table-row": + buffer.append("\n||") + for cell in item.childNodes: + buffer.append(self.inline_markup(cell)) + buffer.append("||") + self.lastsegment = cell.tagName + return ''.join(buffer) + + + def toString(self): + """ Converts the document to a string. + FIXME: Result from second call differs from first call + """ + body = self.content.getElementsByTagName("office:body")[0] + text = body.childNodes[0] + + buffer = [] + + paragraphs = [el for el in text.childNodes + if el.tagName in ["draw:page", "text:p", "text:h","text:section", + "text:list", "table:table"]] + + for paragraph in paragraphs: + if paragraph.tagName == "text:list": + text = self.listToString(paragraph) + elif paragraph.tagName == "text:section": + text = self.textToString(paragraph) + elif paragraph.tagName == "table:table": + text = self.tableToString(paragraph) + else: + text = self.paragraphToString(paragraph) + if text: + buffer.append(text) + + if self.footnotes: + + buffer.append("----") + for cite, body in self.footnotes: + buffer.append("%s: %s" % (cite, body)) + + + buffer.append("") + return self.compressCodeBlocks('\n'.join(buffer)) + + + def textToString(self, element): + + buffer = [] + + for node in element.childNodes: + + if node.nodeType == xml.dom.Node.TEXT_NODE: + buffer.append(node.nodeValue) + + elif node.nodeType == xml.dom.Node.ELEMENT_NODE: + tag = node.tagName + + if tag in ("draw:text-box", "draw:frame"): + buffer.append(self.textToString(node)) + + elif tag in ("text:p", "text:h"): + text = self.paragraphToString(node) + if text: + buffer.append(text) + elif tag == "text:list": + buffer.append(self.listToString(node)) + else: + method = self.elements.get(tag) + if method: + buffer.append(method(node)) + else: + buffer.append(" {" + tag + "} ") + + return ''.join(buffer) + + def paragraphToString(self, paragraph, indent = 0): + + dummyParaProps = ParagraphProps() + + style_name = paragraph.getAttribute("text:style-name") + paraProps = self.paragraphStyles.get(style_name, dummyParaProps) + text = self.inline_markup(paragraph) + + if paraProps and not paraProps.code: + text = text.strip() + + if paragraph.tagName == "text:p" and self.lastsegment == "text:p": + text = "\n" + text + + self.lastsegment = paragraph.tagName + + if paraProps.title: + self.hasTitle = 1 + return "= " + text + " =\n" + + outlinelevel = paragraph.getAttribute("text:outline-level") + if outlinelevel: + + level = int(outlinelevel) + if self.hasTitle: level += 1 + + if level >= 1: + return "=" * level + " " + text + " " + "=" * level + "\n" + + elif paraProps.code: + return "{{{\n" + text + "\n}}}\n" + + if paraProps.indented: + return self.wrapParagraph(text, indent = indent, blockquote = True) + + else: + return self.wrapParagraph(text, indent = indent) + + + def wrapParagraph(self, text, indent = 0, blockquote=False): + + counter = 0 + buffer = [] + LIMIT = 50 + + if blockquote: + buffer.append(" ") + + return ''.join(buffer) + text + # Unused from here + for token in text.split(): + + if counter > LIMIT - indent: + buffer.append("\n" + " "*indent) + if blockquote: + buffer.append(" ") + counter = 0 + + buffer.append(token + " ") + counter += len(token) + + return ''.join(buffer) diff --git a/src/odf/odf2xhtml.py b/src/odf/odf2xhtml.py new file mode 100644 index 0000000000..8042f0871f --- /dev/null +++ b/src/odf/odf2xhtml.py @@ -0,0 +1,1264 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +#import pdb +#pdb.set_trace() +import zipfile +import xml.sax +from xml.sax import handler +from xml.sax.xmlreader import InputSource +from xml.sax.saxutils import escape, quoteattr + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, \ + FORMNS, MATHNS, METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, SCRIPTNS, \ + SMILNS, STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS + +# Handling of styles +# +# First there are font face declarations. These set up a font style that will be +# referenced from a text-property. The declaration describes the font making +# it possible for the application to find a similar font should the system not +# have that particular one. The StyleToCSS stores these attributes to be used +# for the CSS2 font declaration. +# +# Then there are default-styles. These set defaults for various style types: +# "text", "paragraph", "section", "ruby", "table", "table-column", "table-row", +# "table-cell", "graphic", "presentation", "drawing-page", "chart". +# Since CSS2 can't refer to another style, ODF2XHTML add these to all +# styles unless overridden. +# +# The real styles are declared in the <style:style> element. They have a +# family referring to the default-styles, and may have a parent style. +# +# Styles have scope. The same name can be used for both paragraph and +# character etc. styles Since CSS2 has no scope we use a prefix. (Not elegant) +# In ODF a style can have a parent, these parents can be chained. + +class StyleToCSS: + """ The purpose of the StyleToCSS class is to contain the rules to convert + ODF styles to CSS2. Since it needs the generic fonts, it would probably + make sense to also contain the Styles in a dict as well.. + """ + + def __init__(self): + # Font declarations + self.fontdict = {} + + # Fill-images from presentations for backgrounds + self.fillimages = {} + + self.ruleconversions = { + (DRAWNS,u'fill-image-name'): self.c_drawfillimage, + (FONS,u"background-color"): self.c_fo, + (FONS,u"border"): self.c_fo, + (FONS,u"border-bottom"): self.c_fo, + (FONS,u"border-left"): self.c_fo, + (FONS,u"border-right"): self.c_fo, + (FONS,u"border-top"): self.c_fo, + (FONS,u"color"): self.c_fo, + (FONS,u"font-family"): self.c_fo, + (FONS,u"font-size"): self.c_fo, + (FONS,u"font-style"): self.c_fo, + (FONS,u"font-variant"): self.c_fo, + (FONS,u"font-weight"): self.c_fo, + (FONS,u"line-height"): self.c_fo, + (FONS,u"margin"): self.c_fo, + (FONS,u"margin-bottom"): self.c_fo, + (FONS,u"margin-left"): self.c_fo, + (FONS,u"margin-right"): self.c_fo, + (FONS,u"margin-top"): self.c_fo, + (FONS,u"min-height"): self.c_fo, + (FONS,u"padding"): self.c_fo, + (FONS,u"padding-bottom"): self.c_fo, + (FONS,u"padding-left"): self.c_fo, + (FONS,u"padding-right"): self.c_fo, + (FONS,u"padding-top"): self.c_fo, + (FONS,u"page-width"): self.c_page_width, + (FONS,u"page-height"): self.c_page_height, + (FONS,u"text-align"): self.c_text_align, + (FONS,u"text-indent") :self.c_fo, + (TABLENS,u'border-model') :self.c_border_model, + (STYLENS,u'column-width') : self.c_width, + (STYLENS,u"font-name"): self.c_fn, + (STYLENS,u'horizontal-pos'): self.c_hp, + (STYLENS,u'text-position'): self.c_text_position, + (STYLENS,u'text-line-through-style'): self.c_text_line_through_style, + (STYLENS,u'text-underline-style'): self.c_text_underline_style, + (STYLENS,u'width') : self.c_width, + # FIXME Should do style:vertical-pos here + } + + def save_font(self, name, family, generic): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Fortunately ODF provides generic fallbacks. + Unfortunately they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + This method put the font and fallback into a dictionary + """ + htmlgeneric = "sans-serif" + if generic == "roman": htmlgeneric = "serif" + elif generic == "swiss": htmlgeneric = "sans-serif" + elif generic == "modern": htmlgeneric = "monospace" + elif generic == "decorative": htmlgeneric = "sans-serif" + elif generic == "script": htmlgeneric = "monospace" + elif generic == "system": htmlgeneric = "serif" + self.fontdict[name] = (family, htmlgeneric) + + def c_drawfillimage(self, ruleset, sdict, rule, val): + """ Fill a figure with an image. Since CSS doesn't let you resize images + this should really be implemented as an absolutely position <img> + with a width and a height + """ + sdict['background-image'] = "url('%s')" % self.fillimages[val] + + def c_fo(self, ruleset, sdict, rule, val): + """ XSL formatting attributes """ + selector = rule[1] + sdict[selector] = val + + def c_border_model(self, ruleset, sdict, rule, val): + """ Convert to CSS2 border model """ + if val == 'collapsing': + sdict['border-collapse'] ='collapse' + else: + sdict['border-collapse'] ='separate' + + def c_width(self, ruleset, sdict, rule, val): + """ Set width of box """ + sdict['width'] = val + + def c_text_align(self, ruleset, sdict, rule, align): + """ Text align """ + if align == "start": align = "left" + if align == "end": align = "right" + sdict['text-align'] = align + + def c_fn(self, ruleset, sdict, rule, fontstyle): + """ Generate the CSS font family + A generic font can be found in two ways. In a <style:font-face> + element or as a font-family-generic attribute in text-properties. + """ + generic = ruleset.get((STYLENS,'font-family-generic') ) + if generic is not None: + self.save_font(fontstyle, fontstyle, generic) + family, htmlgeneric = self.fontdict.get(fontstyle, (fontstyle, 'serif')) + sdict['font-family'] = '%s, %s' % (family, htmlgeneric) + + def c_text_position(self, ruleset, sdict, rule, tp): + """ Text position. This is used e.g. to make superscript and subscript + This attribute can have one or two values. + + The first value must be present and specifies the vertical + text position as a percentage that relates to the current font + height or it takes one of the values sub or super. Negative + percentages or the sub value place the text below the + baseline. Positive percentages or the super value place + the text above the baseline. If sub or super is specified, + the application can choose an appropriate text position. + + The second value is optional and specifies the font height + as a percentage that relates to the current font-height. If + this value is not specified, an appropriate font height is + used. Although this value may change the font height that + is displayed, it never changes the current font height that + is used for additional calculations. + """ + textpos = tp.split(' ') + if len(textpos) == 2 and textpos[0] != "0%": + # Bug in OpenOffice. If vertical-align is 0% - ignore the text size. + sdict['font-size'] = textpos[1] + if textpos[0] == "super": + sdict['vertical-align'] = "33%" + elif textpos[0] == "sub": + sdict['vertical-align'] = "-33%" + else: + sdict['vertical-align'] = textpos[0] + + def c_hp(self, ruleset, sdict, rule, hpos): + #FIXME: Frames wrap-style defaults to 'parallel', graphics to 'none'. + # It is properly set in the parent-styles, but the program doesn't + # collect the information. + wrap = ruleset.get((STYLENS,'wrap'),'parallel') + # Can have: from-left, left, center, right, from-inside, inside, outside + if hpos == "center": + sdict['margin-left'] = "auto" + sdict['margin-right'] = "auto" + else: + # force it to be *something* then delete it + sdict['margin-left'] = sdict['margin-right'] = '' + del sdict['margin-left'], sdict['margin-right'] + + if hpos in ("right","outside"): + if wrap in ( "left", "parallel","dynamic"): + sdict['float'] = "right" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['right'] = "0"; + else: # No wrapping + sdict['margin-left'] = "auto" + sdict['margin-right'] = "0px" + elif hpos in ("left", "inside"): + if wrap in ( "right", "parallel","dynamic"): + sdict['float'] = "left" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['left'] = "0" + else: # No wrapping + sdict['margin-left'] = "0px" + sdict['margin-right'] = "auto" + elif hpos in ("from-left", "from-inside"): + if wrap in ( "right", "parallel"): + sdict['float'] = "left" + else: + sdict['position'] = "relative" # No wrapping + if ruleset.has_key( (SVGNS,'x') ): + sdict['left'] = ruleset[(SVGNS,'x')] + + def c_page_width(self, ruleset, sdict, rule, val): + """ Set width of box + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + sdict['width'] = val + + def c_text_underline_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "underline" + + def c_text_line_through_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "line-through" + + def c_page_height(self, ruleset, sdict, rule, val): + """ Set height of box """ + sdict['height'] = val + + def convert_styles(self, ruleset): + """ Rule is a tuple of (namespace, name). If the namespace is '' then + it is already CSS2 + """ + sdict = {} + for rule,val in ruleset.items(): + if rule[0] == '': + sdict[rule[1]] = val + continue + method = self.ruleconversions.get(rule, None ) + if method: + method(ruleset, sdict, rule, val) + return sdict + + +class TagStack: + def __init__(self): + self.stack = [] + + def push(self, tag, attrs): + self.stack.append( (tag, attrs) ) + + def pop(self): + item = self.stack.pop() + return item + + def stackparent(self): + item = self.stack[-1] + return item[1] + + def rfindattr(self, attr): + """ Find a tag with the given attribute """ + for tag, attrs in self.stack: + if attrs.has_key(attr): + return attrs[attr] + return None + def count_tags(self, tag): + c = 0 + for ttag, tattrs in self.stack: + if ttag == tag: c = c + 1 + return c + +special_styles = { + 'S-Emphasis':'em', + 'S-Citation':'cite', + 'S-Strong_20_Emphasis':'strong', + 'S-Variable':'var', + 'S-Definition':'dfn', + 'S-Teletype':'tt', + 'P-Heading_20_1':'h1', + 'P-Heading_20_2':'h2', + 'P-Heading_20_3':'h3', + 'P-Heading_20_4':'h4', + 'P-Heading_20_5':'h5', + 'P-Heading_20_6':'h6', +# 'P-Caption':'caption', + 'P-Addressee':'address', +# 'P-List_20_Heading':'dt', +# 'P-List_20_Contents':'dd', + 'P-Preformatted_20_Text':'pre', +# 'P-Table_20_Heading':'th', +# 'P-Table_20_Contents':'td', +# 'P-Text_20_body':'p' +} + +#----------------------------------------------------------------------------- +# +# ODFCONTENTHANDLER +# +#----------------------------------------------------------------------------- +class ODF2XHTML(handler.ContentHandler): + """ The ODF2XHTML parses an ODF file and produces XHTML""" + + def __init__(self): + # Tags + self.elements = { + (DCNS, 'title'): (self.s_processcont, self.e_dc_title), + (DCNS, 'language'): (self.s_processcont, self.e_dc_contentlanguage), + (DCNS, 'creator'): (self.s_processcont, self.e_dc_metatag), + (DCNS, 'description'): (self.s_processcont, self.e_dc_metatag), + (DCNS, 'date'): (self.s_processcont, self.e_dc_metatag), + (DRAWNS, 'frame'): (self.s_draw_frame, self.e_draw_frame), + (DRAWNS, 'image'): (self.s_draw_image, None), + (DRAWNS, 'fill-image'): (self.s_draw_fill_image, None), + (DRAWNS, "layer-set"):(self.s_ignorexml, None), + (DRAWNS, 'page'): (self.s_draw_page, self.e_draw_page), + (METANS, 'creation-date'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'generator'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'initial-creator'): (self.s_processcont, self.e_dc_metatag), + (METANS, 'keyword'): (self.s_processcont, self.e_dc_metatag), + (NUMBERNS, "boolean-style"):(self.s_ignorexml, None), + (NUMBERNS, "currency-style"):(self.s_ignorexml, None), + (NUMBERNS, "date-style"):(self.s_ignorexml, None), + (NUMBERNS, "number-style"):(self.s_ignorexml, None), + (NUMBERNS, "text-style"):(self.s_ignorexml, None), + (OFFICENS, "automatic-styles"):(self.s_office_automatic_styles, None), + (OFFICENS, "document-content"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "forms"):(self.s_ignorexml, None), + (OFFICENS, "master-styles"):(self.s_office_master_styles, None), + (OFFICENS, "meta"):(self.s_ignorecont, None), + (OFFICENS, "presentation"):(self.s_office_presentation, self.e_office_presentation), + (OFFICENS, "spreadsheet"):(self.s_office_spreadsheet, self.e_office_spreadsheet), + (OFFICENS, "styles"):(self.s_office_styles, None), + (OFFICENS, "text"):(self.s_office_text, self.e_office_text), + (OFFICENS, "scripts"):(self.s_ignorexml, None), + (PRESENTATIONNS, "notes"):(self.s_ignorexml, None), + (STYLENS, "default-style"):(self.s_style_default_style, self.e_style_default_style), + (STYLENS, "drawing-page-properties"):(self.s_style_handle_properties, None), + (STYLENS, "font-face"):(self.s_style_font_face, None), +# (STYLENS, "footer"):(self.s_style_footer, self.e_style_footer), +# (STYLENS, "footer-style"):(self.s_style_footer_style, None), + (STYLENS, "graphic-properties"):(self.s_style_handle_properties, None), + (STYLENS, "handout-master"):(self.s_ignorexml, None), +# (STYLENS, "header"):(self.s_style_header, self.e_style_header), +# (STYLENS, "header-footer-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "header-style"):(self.s_style_header_style, None), + (STYLENS, "master-page"):(self.s_style_master_page, None), + (STYLENS, "page-layout-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "page-layout"):(self.s_style_page_layout, self.e_style_page_layout), + (STYLENS, "page-layout"):(self.s_ignorexml, None), + (STYLENS, "paragraph-properties"):(self.s_style_handle_properties, None), + (STYLENS, "style"):(self.s_style_style, self.e_style_style), + (STYLENS, "table-cell-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-column-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-properties"):(self.s_style_handle_properties, None), + (STYLENS, "text-properties"):(self.s_style_handle_properties, None), + (SVGNS, 'desc'): (self.s_ignorexml, None), + (TABLENS, 'covered-table-cell'): (self.s_ignorexml, None), + (TABLENS, 'table-cell'): (self.s_table_table_cell, self.e_table_table_cell), + (TABLENS, 'table-column'): (self.s_table_table_column, None), + (TABLENS, 'table-row'): (self.s_table_table_row, self.e_table_table_row), + (TABLENS, 'table'): (self.s_table_table, self.e_table_table), + (TEXTNS, 'a'): (self.s_text_a, self.e_text_a), + (TEXTNS, "alphabetical-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "bibliography-configuration"):(self.s_ignorexml, None), + (TEXTNS, "bibliography-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'h'): (self.s_text_h, self.e_text_h), + (TEXTNS, "illustration-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'line-break'):(self.s_text_line_break, None), + (TEXTNS, "linenumbering-configuration"):(self.s_ignorexml, None), + (TEXTNS, "list"):(self.s_text_list, self.e_text_list), + (TEXTNS, "list-item"):(self.s_text_list_item, self.e_text_list_item), + (TEXTNS, "list-level-style-bullet"):(self.s_text_list_level_style_bullet, self.e_text_list_level_style_bullet), + (TEXTNS, "list-level-style-number"):(self.s_text_list_level_style_number, self.e_text_list_level_style_number), + (TEXTNS, "list-style"):(None, None), + (TEXTNS, "note"):(self.s_text_note, None), + (TEXTNS, "note-body"):(self.s_text_note_body, self.e_text_note_body), + (TEXTNS, "note-citation"):(None, self.e_text_note_citation), + (TEXTNS, "notes-configuration"):(self.s_ignorexml, None), + (TEXTNS, "object-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'p'): (self.s_text_p, self.e_text_p), + (TEXTNS, 's'): (self.s_text_s, None), + (TEXTNS, 'span'): (self.s_text_span, self.e_text_span), + (TEXTNS, 'tab'): (self.s_text_tab, None), + (TEXTNS, "table-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "table-of-content-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "user-index-source"):(self.s_text_x_source, self.e_text_x_source), + } + + def writeout(self, s): + if s != '': + self._wfunc(s) + + def writedata(self): + d = ''.join(self.data) + if d != '': + self.writeout(escape(d)) + + def opentag(self, tag, attrs={}, block=False): + """ Create an open HTML tag """ + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + if len(a) == 0: + self.writeout("<%s>" % tag) + else: + self.writeout("<%s %s>" % (tag, " ".join(a))) + if block == True: + self.writeout("\n") + + def closetag(self, tag, block=True): + self.writeout("</%s>" % tag) + if block == True: + self.writeout("\n") + + def emptytag(self, tag, attrs={}): + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + self.writeout("<%s %s/>\n" % (tag, " ".join(a))) + +#-------------------------------------------------- + def characters(self, data): + if self.processelem and self.processcont: + self.data.append(data) + + def handle_starttag(self, tag, method, attrs): + method(tag,attrs) + + def handle_endtag(self, tag, attrs, method): + method(tag, attrs) + + def startElementNS(self, tag, qname, attrs): + self.pstack.append( (self.processelem, self.processcont) ) + if self.processelem: + method = self.elements.get(tag, (None, None) )[0] + if method: + self.handle_starttag(tag, method, attrs) + else: + self.unknown_starttag(tag,attrs) + self.tagstack.push( tag, attrs ) + + def endElementNS(self, tag, qname): + stag, attrs = self.tagstack.pop() + if self.processelem: + method = self.elements.get(tag, (None, None) )[1] + if method: + self.handle_endtag(tag, attrs, method) + else: + self.unknown_endtag(tag, attrs) + self.processelem, self.processcont = self.pstack.pop() + + def unknown_starttag(self, tag, attrs): + pass + + def unknown_endtag(self, tag, attrs): + pass + + def s_ignorexml(self, tag, attrs): + """ Ignore this xml element and all children of it + It will automatically stop ignoring + """ + self.processelem = False + + def s_ignorecont(self, tag, attrs): + self.processcont = False + + def s_processcont(self, tag, attrs): + self.processcont = True + + def classname(self, attrs): + """ Generate a class name from a style name """ + c = attrs[(TEXTNS,'style-name')] + c = c.replace(".","_") + return c + + def get_anchor(self, name): + if not self.anchors.has_key(name): + self.anchors[name] = "anchor%03d" % (len(self.anchors) + 1) + return self.anchors.get(name) + + +#-------------------------------------------------- + + def purgedata(self): + self.data = [] + +#----------------------------------------------------------------------------- +# +# Handle meta data +# +#----------------------------------------------------------------------------- + def e_dc_title(self, tag, attrs): + """ Get the title from the meta data and create a HTML <title> + """ + self.metatags.append('<title>%s\n' % escape(''.join(self.data))) + self.title = ''.join(self.data) + self.data = [] + + def e_dc_metatag(self, tag, attrs): + """ Any other meta data is added as a element + """ + self.metatags.append('\n' % (tag[1], quoteattr(''.join(self.data)))) + self.data = [] + + def e_dc_contentlanguage(self, tag, attrs): + """ Set the content language. Identifies the targeted audience + """ + self.metatags.append('\n' % ''.join(self.data)) + self.data = [] + + def s_draw_frame(self, tag, attrs): + """ A is made into a
            in HTML which is then styled + """ + anchor_type = attrs.get((TEXTNS,'anchor-type'),'char') + name = "G-" + attrs.get( (DRAWNS,'style-name'), "") + if name == 'G-': + name = "PR-" + attrs.get( (PRESENTATIONNS,'style-name'), "") + name = name.replace(".","_") + if anchor_type == "paragraph": + style = "" + elif anchor_type == 'char': + style = "position: relative;" + else: + style = "position: absolute;" + if attrs.has_key( (SVGNS,"width") ): + style = style + "width:" + attrs[(SVGNS,"width")] + ";" + if attrs.has_key( (SVGNS,"height") ): + style = style + "height:" + attrs[(SVGNS,"height")] + ";" + if attrs.has_key( (SVGNS,"x") ): + style = style + "left:" + attrs[(SVGNS,"x")] + ";" + if attrs.has_key( (SVGNS,"y") ): + style = style + "top:" + attrs[(SVGNS,"y")] + ";" + self.opentag('div', {'class': name, 'style': style}) + + def e_draw_frame(self, tag, attrs): + """ End the + """ + self.closetag('div') + + def s_draw_fill_image(self, tag, attrs): + name = attrs.get( (DRAWNS,'name'), "NoName") + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + self.cs.fillimages[name] = imghref + + def rewritelink(self, imghref): + """ Intended to be overloaded if you don't store your pictures + in a Pictures subfolder + """ + return imghref + + def s_draw_image(self, tag, attrs): + """ A becomes an element + """ + parent = self.tagstack.stackparent() + anchor_type = parent.get((TEXTNS,'anchor-type')) + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + htmlattrs = {'alt':"", 'src':imghref } + if anchor_type != "char": + htmlattrs['style'] = "display: block;" + self.emptytag('img', htmlattrs) + + def s_draw_page(self, tag, attrs): + """ A is a slide in a presentation. We use a
            element in HTML. + Therefore if you convert a ODP file, you get a series of
            s. + Override this for your own purpose. + """ + name = attrs.get( (DRAWNS,'name'), "NoName") + stylename = attrs.get( (DRAWNS,'style-name'), "") + stylename = stylename.replace(".","_") + masterpage = attrs.get( (DRAWNS,'master-page-name'),"") + masterpage = masterpage.replace(".","_") + self.opentag('fieldset', {'class':"DP-%s MP-%s" % (stylename, masterpage) }) + self.opentag('legend') + self.writeout(escape(name)) + self.closetag('legend') + + def e_draw_page(self, tag, attrs): + self.closetag('fieldset') + + def html_body(self, tag, attrs): + self.writedata() + self.opentag('style', {'type':"text/css"}, True) + self.writeout('/**/\n') + self.closetag('style') + self.purgedata() + self.closetag('head') + self.opentag('body', block=True) + + def generate_stylesheet(self): + for name in self.stylestack: + styles = self.styledict.get(name) + # Preload with the family's default style + if styles.has_key('__style-family') and self.styledict.has_key(styles['__style-family']): + familystyle = self.styledict[styles['__style-family']].copy() + del styles['__style-family'] + for style, val in styles.items(): + familystyle[style] = val + styles = familystyle + # Resolve the remaining parent styles + while styles.has_key('__parent-style-name') and self.styledict.has_key(styles['__parent-style-name']): + parentstyle = self.styledict[styles['__parent-style-name']].copy() + del styles['__parent-style-name'] + for style, val in styles.items(): + parentstyle[style] = val + styles = parentstyle + self.styledict[name] = styles + # Write the styles to HTML + for name in self.stylestack: + styles = self.styledict.get(name) + css2 = self.cs.convert_styles(styles) + self.writeout("%s {\n" % name) + for style, val in css2.items(): + self.writeout("\t%s: %s;\n" % (style, val) ) + self.writeout("}\n") + + def generate_footnotes(self): + if self.currentnote == 0: + return + self.opentag('ol', {'style':'border-top: 1px solid black'}, True) + for key in range(1,self.currentnote+1): + note = self.notedict[key] +# for key,note in self.notedict.items(): + self.opentag('li', { 'id':"footnote-%d" % key }) +# self.opentag('sup') +# self.writeout(escape(note['citation'])) +# self.closetag('sup', False) + self.writeout(note['body']) + self.closetag('li') + self.closetag('ol') + + def s_office_automatic_styles(self, tag, attrs): + if self.xmlfile == 'styles.xml': + self.autoprefix = "A" + else: + self.autoprefix = "" + + def s_office_document_content(self, tag, attrs): + """ First tag in the content.xml file""" + self.writeout('\n') + self.opentag('html', {'xmlns':"http://www.w3.org/1999/xhtml"}, True) + self.opentag('head', block=True) + self.emptytag('meta', { 'http-equiv':"Content-Type", 'content':"text/html;charset=UTF-8"}) + for metaline in self.metatags: + self.writeout(metaline) + + def e_office_document_content(self, tag, attrs): + """ Last tag """ + self.closetag('html') + + def s_office_master_styles(self, tag, attrs): + """ """ + + def s_office_presentation(self, tag, attrs): + """ For some odd reason, OpenOffice Impress doesn't define a default-style + for the 'paragraph'. We therefore force a standard when we see + it is a presentation + """ + self.styledict['p'] = {(FONS,u'font-size'): u"24pt" } + self.styledict['presentation'] = {(FONS,u'font-size'): u"24pt" } + self.html_body(tag, attrs) + + def e_office_presentation(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_spreadsheet(self, tag, attrs): + self.html_body(tag, attrs) + + def e_office_spreadsheet(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_styles(self, tag, attrs): + self.autoprefix = "" + + def s_office_text(self, tag, attrs): + """ OpenDocument text """ + self.styledict['frame'] = { (STYLENS,'wrap'): u'parallel'} + self.html_body(tag, attrs) + + def e_office_text(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_style_handle_properties(self, tag, attrs): + """ Copy all attributes to a struct. + We will later convert them to CSS2 + """ + for key,attr in attrs.items(): + self.styledict[self.currentstyle][key] = attr + + + familymap = {'frame':'frame', 'paragraph':'p', 'presentation':'presentation', + 'text':'span','section':'div', + 'table':'table','table-cell':'td','table-column':'col', + 'table-row':'tr','graphic':'graphic' } + + def s_style_default_style(self, tag, attrs): + """ A default style is like a style on an HTML tag + """ + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + self.currentstyle = htmlfamily +# self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_default_style(self, tag, attrs): + self.currentstyle = None + + def s_style_font_face(self, tag, attrs): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Luckily ODF provides generic fallbacks + Unluckily they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + """ + name = attrs[(STYLENS,"name")] + family = attrs[(SVGNS,"font-family")] + generic = attrs.get( (STYLENS,'font-family-generic'),"" ) + self.cs.save_font(name, family, generic) + + def s_style_footer(self, tag, attrs): + self.opentag('div', { 'id':"footer" }) + self.purgedata() + + def e_style_footer(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_footer_style(self, tag, attrs): + self.currentstyle = "@print #footer" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_header(self, tag, attrs): + self.opentag('div', { 'id':"header" }) + self.purgedata() + + def e_style_header(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_header_style(self, tag, attrs): + self.currentstyle = "@print #header" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_page_layout(self, tag, attrs): + """ Collect the formatting for the page layout style. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + self.currentstyle = "@page " + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_page_layout(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_style_master_page(self, tag, attrs): + """ Collect the formatting for the page layout style. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + + self.currentstyle = ".MP-" + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {('','position'):'relative'} + # Then load the pagelayout style if we find it + pagelayout = attrs.get( (STYLENS,'page-layout-name'), None) + if pagelayout: + pagelayout = ".PL-" + pagelayout + if self.styledict.has_key( pagelayout ): + styles = self.styledict[pagelayout] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = pagelayout + self.s_ignorexml(tag, attrs) + + # Short prefixes for class selectors + familyshort = {'drawing-page':'DP', 'paragraph':'P', 'presentation':'PR', + 'text':'S', 'section':'D', + 'table':'T', 'table-cell':'TD', 'table-column':'TC', + 'table-row':'TR', 'graphic':'G' } + + def s_style_style(self, tag, attrs): + """ Collect the formatting for the style. + Styles have scope. The same name can be used for both paragraph and + character styles Since CSS has no scope we use a prefix. (Not elegant) + In ODF a style can have a parent, these parents can be chained. + We may not have encountered the parent yet, but if we have, we resolve it. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + sfamily = self.familyshort.get(family,'X') + name = "%s%s-%s" % (self.autoprefix, sfamily, name) + parent = attrs.get( (STYLENS,'parent-style-name') ) + self.currentstyle = special_styles.get(name,"."+name) + self.stylestack.append(self.currentstyle) + if not self.styledict.has_key(self.currentstyle): + self.styledict[self.currentstyle] = {} + + self.styledict[self.currentstyle]['__style-family'] = htmlfamily + + # Then load the parent style if we find it + if parent: + parent = "%s-%s" % (sfamily, parent) + parent = special_styles.get(parent, "."+parent) + if self.styledict.has_key( parent ): + styles = self.styledict[parent] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = parent + + def e_style_style(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_table_table(self, tag, attrs): + """ Start a table + """ + c = attrs.get( (TABLENS,'style-name'), None) + if c: + c = c.replace(".","_") + self.opentag('table',{ 'class': "T-%s" % c }) + else: + self.opentag('table') + self.purgedata() + + def e_table_table(self, tag, attrs): + """ End a table + """ + self.writedata() + self.closetag('table') + self.purgedata() + + def s_table_table_cell(self, tag, attrs): + #FIXME: number-columns-repeated § 8.1.3 + #repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + rowspan = attrs.get( (TABLENS,'number-rows-spanned') ) + if rowspan: + htmlattrs['rowspan'] = rowspan + colspan = attrs.get( (TABLENS,'number-columns-spanned') ) + if colspan: + htmlattrs['colspan'] = colspan + + c = attrs.get( (TABLENS,'style-name') ) + if c: + htmlattrs['class'] = 'TD-%s' % c.replace(".","_") + self.opentag('td', htmlattrs) + self.purgedata() + + def e_table_table_cell(self, tag, attrs): + self.writedata() + self.closetag('td') + self.purgedata() + + def s_table_table_column(self, tag, attrs): + c = attrs.get( (TABLENS,'style-name'), None) + repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + if c: + htmlattrs['class'] = "TC-%s" % c.replace(".","_") + for x in xrange(repeated): + self.emptytag('col', htmlattrs) + self.purgedata() + + def s_table_table_row(self, tag, attrs): + #FIXME: table:number-rows-repeated + c = attrs.get( (TABLENS,'style-name'), None) + htmlattrs = {} + if c: + htmlattrs['class'] = "TR-%s" % c.replace(".","_") + self.opentag('tr', htmlattrs) + self.purgedata() + + def e_table_table_row(self, tag, attrs): + self.writedata() + self.closetag('tr') + self.purgedata() + + def s_text_a(self, tag, attrs): + """ Anchors start """ + self.writedata() + href = attrs[(XLINKNS,"href")].split("|")[0] + if href[0] == "#": + href = "#" + self.get_anchor(href[1:]) + self.opentag('a', {'href':href}) + self.purgedata() + + def e_text_a(self, tag, attrs): + self.writedata() + self.closetag('a', False) + self.purgedata() + + def s_text_h(self, tag, attrs): + """ Headings start """ + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + self.headinglevels[level] = self.headinglevels[level] + 1 + name = self.classname(attrs) + for x in range(level + 1,10): + self.headinglevels[x] = 0 + special = special_styles.get("P-"+name) + if special: + self.opentag('h%s' % level) + else: + self.opentag('h%s' % level, {'class':"P-%s" % name }) + self.purgedata() + + def e_text_h(self, tag, attrs): + """ Headings end """ + self.writedata() + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + lev = self.headinglevels[1:level+1] + outline = '.'.join(map(str,lev) ) + anchor = self.get_anchor("%s.%s" % ( outline, ''.join(self.data))) + self.opentag('a', {'id': anchor} ) + self.closetag('a', False) + self.closetag('h%s' % level) + self.purgedata() + + def s_text_line_break(self, tag, attrs): + self.writedata() + self.emptytag('br') + self.purgedata() + + def s_text_list(self, tag, attrs): + """ To know which level we're at, we have to count the number + of elements on the tagstack. + """ + name = attrs.get( (TEXTNS,'style-name') ) + if name: + name = name.replace(".","_") + level = 1 + else: + # FIXME: If a list is contained in a table cell or text box, + # the list level must return to 1, even though the table or + # textbox itself may be nested within another list. + level = self.tagstack.count_tags(tag) + 1 + name = self.tagstack.rfindattr( (TEXTNS,'style-name') ) + self.opentag('%s' % self.listtypes.get(name), {'class':"%s_%d" % (name, level) }) + self.purgedata() + + def e_text_list(self, tag, attrs): + self.writedata() + name = attrs.get( (TEXTNS,'style-name') ) + if name: + name = name.replace(".","_") + level = 1 + else: + # FIXME: If a list is contained in a table cell or text box, + # the list level must return to 1, even though the table or + # textbox itself may be nested within another list. + level = self.tagstack.count_tags(tag) + 1 + name = self.tagstack.rfindattr( (TEXTNS,'style-name') ) + self.closetag(self.listtypes.get(name)) + self.purgedata() + + def s_text_list_item(self, tag, attrs): + self.opentag('li') + self.purgedata() + + def e_text_list_item(self, tag, attrs): + self.writedata() + self.closetag('li') + self.purgedata() + + def s_text_list_level_style_bullet(self, tag, attrs): + """ CSS doesn't have the ability to set the glyph + to a particular character, so we just go through + the available glyphs + """ + name = self.tagstack.rfindattr( (STYLENS,'name') ) + self.listtypes[name] = 'ul' + level = attrs[(TEXTNS,'level')] + self.prevstyle = self.currentstyle + self.currentstyle = ".%s_%s" % ( name.replace(".","_"), level) + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + level = int(level) + listtype = ("square", "disc", "circle")[level % 3] + self.styledict[self.currentstyle][('','list-style-type')] = listtype + + def e_text_list_level_style_bullet(self, tag, attrs): + self.currentstyle = self.prevstyle + del self.prevstyle + + def s_text_list_level_style_number(self, tag, attrs): + name = self.tagstack.stackparent()[(STYLENS,'name')] + self.listtypes[name] = 'ol' + level = attrs[(TEXTNS,'level')] + num_format = attrs.get( (STYLENS,'name'),"1") + self.prevstyle = self.currentstyle + self.currentstyle = ".%s_%s" % ( name.replace(".","_"), level) + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + if num_format == "1": listtype = "decimal" + elif num_format == "I": listtype = "upper-roman" + elif num_format == "i": listtype = "lower-roman" + elif num_format == "A": listtype = "upper-alpha" + elif num_format == "a": listtype = "lower-alpha" + else: listtype = "decimal" + self.styledict[self.currentstyle][('','list-style-type')] = listtype + + def e_text_list_level_style_number(self, tag, attrs): + self.currentstyle = self.prevstyle + del self.prevstyle + + def s_text_note(self, tag, attrs): + self.writedata() + self.purgedata() + self.currentnote = self.currentnote + 1 + self.notedict[self.currentnote] = {} + self.notebody = [] + + def e_text_note(self, tag, attrs): + pass + + def collectnote(self,s): + if s != '': + self.notebody.append(s) + + def s_text_note_body(self, tag, attrs): + self._orgwfunc = self._wfunc + self._wfunc = self.collectnote + + def e_text_note_body(self, tag, attrs): + self._wfunc = self._orgwfunc + self.notedict[self.currentnote]['body'] = ''.join(self.notebody) + self.notebody = '' + del self._orgwfunc + + def e_text_note_citation(self, tag, attrs): + mark = ''.join(self.data) + self.notedict[self.currentnote]['citation'] = mark + self.opentag('a',{ 'href': "#footnote-%s" % self.currentnote }) + self.opentag('sup') +# self.writeout( escape(mark) ) + # Since HTML only knows about endnotes, there is too much risk that the + # marker is reused in the source. Therefore we force numeric markers + self.writeout(unicode(self.currentnote)) + self.closetag('sup') + self.closetag('a') + + def s_text_p(self, tag, attrs): + """ Paragraph + """ + htmlattrs = {} + specialtag = "p" + c = attrs.get( (TEXTNS,'style-name'), None) + if c: + c = c.replace(".","_") + specialtag = special_styles.get("P-"+c) + if specialtag is None: + specialtag = 'p' + htmlattrs['class'] = "P-%s" % c + self.opentag(specialtag, htmlattrs) + self.purgedata() + + def e_text_p(self, tag, attrs): + """ End Paragraph + """ + specialtag = "p" + c = attrs.get( (TEXTNS,'style-name'), None) + if c: + c = c.replace(".","_") + specialtag = special_styles.get("P-"+c) + if specialtag is None: + specialtag = 'p' + self.writedata() + self.closetag(specialtag) + self.purgedata() + + def s_text_s(self, tag, attrs): + """ Generate a number of spaces. ODF has an element; HTML uses   + We use   so we can send the output through an XML parser if we desire to + """ + c = attrs.get( (TEXTNS,'c'),"1") + for x in xrange(int(c)): + self.writeout(' ') + + def s_text_span(self, tag, attrs): + """ The element matches the element in HTML. It is + typically used to properties of the text. + """ + self.writedata() + c = attrs.get( (TEXTNS,'style-name'), None) + htmlattrs = {} + if c: + c = c.replace(".","_") + special = special_styles.get("S-"+c) + if special is None: + htmlattrs['class'] = "S-%s" % c + self.opentag('span', htmlattrs) + self.purgedata() + + def e_text_span(self, tag, attrs): + """ End the """ + self.writedata() + self.closetag('span', False) + self.purgedata() + + def s_text_tab(self, tag, attrs): + """ Move to the next tabstop. We ignore this in HTML + """ + self.writedata() + self.writeout(' ') + self.purgedata() + + def s_text_x_source(self, tag, attrs): + """ Various indexes and tables of contents. We ignore those. + """ + self.writedata() + self.purgedata() + self.s_ignorexml(tag, attrs) + + def e_text_x_source(self, tag, attrs): + """ Various indexes and tables of contents. We ignore those. + """ + self.writedata() + self.purgedata() + + +#----------------------------------------------------------------------------- +# +# Reading the file +# +#----------------------------------------------------------------------------- + + def load(self, odffile): + self._odffile = odffile + + def parseodf(self): + self.xmlfile = '' + self.title = '' + self.data = [] + self.tagstack = TagStack() + self.pstack = [] + self.processelem = True + self.processcont = True + self.listtypes = {} + self.headinglevels = [0, 0,0,0,0,0, 0,0,0,0,0] # level 0 to 10 + self.cs = StyleToCSS() + self.anchors = {} + + # Style declarations + self.stylestack = [] + self.styledict = {} + self.currentstyle = None + + # Footnotes and endnotes + self.notedict = {} + self.currentnote = 0 + self.notebody = '' + + # Tags from meta.xml + self.metatags = [] + + # Extract the interesting files + z = zipfile.ZipFile(self._odffile) + + parser = xml.sax.make_parser() + parser.setFeature(handler.feature_namespaces, 1) + parser.setContentHandler(self) + parser.setErrorHandler(handler.ErrorHandler()) + inpsrc = InputSource() + + for xmlfile in ('meta.xml', 'styles.xml', 'content.xml'): + self.xmlfile = xmlfile + content = z.read(xmlfile) + inpsrc.setByteStream(StringIO(content)) + parser.parse(inpsrc) + z.close() + + def odf2xhtml(self, odffile): + """ Load a file and return XHTML + """ + self.load(odffile) + return self.xhtml() + + def _wlines(self,s): + if s != '': self.lines.append(s) + + def xhtml(self): + self.lines = [] + self._wfunc = self._wlines + self.parseodf() + return ''.join(self.lines) + + def _writecss(self, s): + if s != '': self._csslines.append(s) + + def _writenothing(self, s): + pass + + def css(self): + self._wfunc = self._writenothing + self.parseodf() + self._csslines = [] + self._wfunc = self._writecss + self.generate_stylesheet() + res = ''.join(self._csslines) + del self._csslines + return res diff --git a/src/odf/odfmanifest.py b/src/odf/odfmanifest.py new file mode 100644 index 0000000000..fef00c927d --- /dev/null +++ b/src/odf/odfmanifest.py @@ -0,0 +1,120 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +# This script lists the content of the manifest.xml file +import zipfile +from xml.sax import make_parser,handler +from xml.sax.xmlreader import InputSource +import xml.sax.saxutils + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + + +MANIFESTNS="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" + +#----------------------------------------------------------------------------- +# +# ODFMANIFESTHANDLER +# +#----------------------------------------------------------------------------- + +class ODFManifestHandler(handler.ContentHandler): + """ The ODFManifestHandler parses a manifest file and produces a list of + content """ + + def __init__(self): + self.manifest = {} + + # Tags + # FIXME: Also handle encryption data + self.elements = { + (MANIFESTNS, 'file-entry'): (self.s_file_entry, self.donothing), + } + + def handle_starttag(self, tag, method, attrs): + method(tag,attrs) + + def handle_endtag(self, tag, method): + method(tag) + + def startElementNS(self, tag, qname, attrs): + method = self.elements.get(tag, (None, None))[0] + if method: + self.handle_starttag(tag, method, attrs) + else: + self.unknown_starttag(tag,attrs) + + def endElementNS(self, tag, qname): + method = self.elements.get(tag, (None, None))[1] + if method: + self.handle_endtag(tag, method) + else: + self.unknown_endtag(tag) + + def unknown_starttag(self, tag, attrs): + pass + + def unknown_endtag(self, tag): + pass + + def donothing(self, tag, attrs=None): + pass + + def s_file_entry(self, tag, attrs): + m = attrs.get((MANIFESTNS, 'media-type'),"application/octet-stream") + p = attrs.get((MANIFESTNS, 'full-path')) + self.manifest[p] = { 'media-type':m, 'full-path':p } + + +#----------------------------------------------------------------------------- +# +# Reading the file +# +#----------------------------------------------------------------------------- + +def manifestlist(manifestxml): + odhandler = ODFManifestHandler() + parser = make_parser() + parser.setFeature(handler.feature_namespaces, 1) + parser.setContentHandler(odhandler) + parser.setErrorHandler(handler.ErrorHandler()) + + inpsrc = InputSource() + inpsrc.setByteStream(StringIO(manifestxml)) + parser.parse(inpsrc) + + return odhandler.manifest + +def odfmanifest(odtfile): + z = zipfile.ZipFile(odtfile) + manifest = z.read('META-INF/manifest.xml') + z.close() + return manifestlist(manifest) + +if __name__ == "__main__": + import sys + result = odfmanifest(sys.argv[1]) + for file in result.values(): + print "%-40s %-40s" % (file['media-type'], file['full-path']) + diff --git a/src/odf/office.py b/src/odf/office.py new file mode 100644 index 0000000000..c4a9fe9c1d --- /dev/null +++ b/src/odf/office.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import OFFICENS +from element import Element +from draw import StyleRefElement + +# Autogenerated +def Annotation(**args): + return StyleRefElement(qname = (OFFICENS,'annotation'), **args) + +def AutomaticStyles(**args): + return Element(qname = (OFFICENS, 'automatic-styles'), **args) + +def BinaryData(**args): + return Element(qname = (OFFICENS,'binary-data'), **args) + +def Body(**args): + return Element(qname = (OFFICENS, 'body'), **args) + +def ChangeInfo(**args): + return Element(qname = (OFFICENS,'change-info'), **args) + +def Chart(**args): + return Element(qname = (OFFICENS,'chart'), **args) + +def DdeSource(**args): + return Element(qname = (OFFICENS,'dde-source'), **args) + +def Document(version="1.0", **args): + return Element(qname = (OFFICENS,'document'), version=version, **args) + +def DocumentContent(version="1.0", **args): + return Element(qname = (OFFICENS, 'document-content'), version=version, **args) + +def DocumentMeta(version="1.0", **args): + return Element(qname = (OFFICENS, 'document-meta'), version=version, **args) + +def DocumentSettings(version="1.0", **args): + return Element(qname = (OFFICENS, 'document-settings'), version=version, **args) + +def DocumentStyles(version="1.0", **args): + return Element(qname = (OFFICENS, 'document-styles'), version=version, **args) + +def Drawing(**args): + return Element(qname = (OFFICENS,'drawing'), **args) + +def EventListeners(**args): + return Element(qname = (OFFICENS,'event-listeners'), **args) + +def FontFaceDecls(**args): + return Element(qname = (OFFICENS, 'font-face-decls'), **args) + +def Forms(**args): + return Element(qname = (OFFICENS,'forms'), **args) + +def Image(**args): + return Element(qname = (OFFICENS,'image'), **args) + +def MasterStyles(**args): + return Element(qname = (OFFICENS, 'master-styles'), **args) + +def Meta(**args): + return Element(qname = (OFFICENS, 'meta'), **args) + +def Presentation(**args): + return Element(qname = (OFFICENS,'presentation'), **args) + +def Script(**args): + return Element(qname = (OFFICENS, 'script'), **args) + +def Scripts(**args): + return Element(qname = (OFFICENS, 'scripts'), **args) + +def Settings(**args): + return Element(qname = (OFFICENS, 'settings'), **args) + +def Spreadsheet(**args): + return Element(qname = (OFFICENS, 'spreadsheet'), **args) + +def Styles(**args): + return Element(qname = (OFFICENS, 'styles'), **args) + +def Text(**args): + return Element(qname = (OFFICENS, 'text'), **args) + +# Autogenerated end diff --git a/src/odf/ooostyles.py b/src/odf/ooostyles.py new file mode 100644 index 0000000000..8600d3ae51 --- /dev/null +++ b/src/odf/ooostyles.py @@ -0,0 +1,71 @@ +from style import Style, ParagraphProperties, TextProperties + +def addOOoStandardStyles(styles): + style = Style(name="Standard", family="paragraph", attributes={'class':"text"}) + styles.addElement(style) + + style = Style(name="Text_20_body", displayname="Text body", family="paragraph", parentstylename="Standard", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0cm", marginbottom="0.212cm") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Text_20_body_20_indent", displayname="Text body indent", family="paragraph", parentstylename="Text_20_body", attributes={'class':"text"}) + p = ParagraphProperties(marginleft="0.499cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Salutation", family="paragraph", parentstylename="Standard", attributes={'class':"text"}) + p = ParagraphProperties(numberlines="false", linenumber=0) + style.addElement(p) + styles.addElement(style) + + style = Style(name="Signature", family="paragraph", parentstylename="Standard", attributes={'class':"text"}) + p = ParagraphProperties(numberlines="false", linenumber=0) + style.addElement(p) + styles.addElement(style) + + style = Style(name="Heading", family="paragraph", parentstylename="Standard", nextstylename="Text_20_body", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0.423cm", marginbottom="0.212cm", keepwithnext="always") + style.addElement(p) + p = TextProperties(fontname="Nimbus Sans L", fontsize="14pt", fontnameasian="DejaVu LGC Sans", fontsizeasian="14pt", fontnamecomplex="DejaVu LGC Sans", fontsizecomplex="14pt") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Heading_20_1", displayname="Heading 1", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=1) + p = TextProperties(fontsize="115%", fontweight="bold", fontsizeasian="115%", fontweightasian="bold", fontsizecomplex="115%", fontweightcomplex="bold") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Heading_20_2", displayname="Heading 2", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=2) + p = TextProperties(fontsize="14pt", fontstyle="italic", fontweight="bold", fontsizeasian="14pt", fontstyleasian="italic", fontweightasian="bold", fontsizecomplex="14pt", fontstylecomplex="italic", fontweightcomplex="bold") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Heading_20_3", displayname="Heading 3", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=3) + p = TextProperties(fontsize="14pt", fontweight="bold", fontsizeasian="14pt", fontweightasian="bold", fontsizecomplex="14pt", fontweightcomplex="bold") + style.addElement(p) + styles.addElement(style) + + style = Style(name="List", family="paragraph", parentstylename="Text_20_body", attributes={'class':"list"}) + styles.addElement(style) + + style = Style(name="Caption", family="paragraph", parentstylename="Standard", attributes={'class':"extra"}) + p = ParagraphProperties(margintop="0.212cm", marginbottom="0.212cm", numberlines="false", linenumber="0") + style.addElement(p) + p = TextProperties(fontsize="12pt", fontstyle="italic", fontsizeasian="12pt", fontstyleasian="italic", fontsizecomplex="12pt", fontstylecomplex="italic") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Index", family="paragraph", parentstylename="Standard", attributes={'class':"index"}) + p = ParagraphProperties(numberlines="false", linenumber=0) + styles.addElement(style) + + style = Style(name="Source_20_Text", displayname="Source Text", family="text") + p = TextProperties(fontname="Courier", fontnameasian="Courier", fontnamecomplex="Courier") + style.addElement(p) + styles.addElement(style) + + style = Style(name="Variable", family="text") + p = TextProperties(fontstyle="italic", fontstyleasian="italic", fontstylecomplex="italic") + style.addElement(p) + styles.addElement(style) diff --git a/src/odf/opendocument.py b/src/odf/opendocument.py new file mode 100644 index 0000000000..aa2ed9aaaf --- /dev/null +++ b/src/odf/opendocument.py @@ -0,0 +1,558 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +__doc__="""Use OpenDocument to generate your documents.""" + +import zipfile, time, sys, mimetypes, copy +from cStringIO import StringIO +from namespaces import * +import manifest, meta +from office import * +import element +from attrconverters import make_NCName +from xml.sax.xmlreader import InputSource +from odfmanifest import manifestlist + +__version__= TOOLSVERSION + +_XMLPROLOGUE = u"\n" + +UNIXPERMS = 0100644 << 16L # -rw-r--r-- + +IS_FILENAME = 0 +IS_IMAGE = 1 +# We need at least Python 2.2 +assert sys.version_info[0]>=2 and sys.version_info[1] >= 2 + +sys.setrecursionlimit=50 +#The recursion limit is set conservative so mistakes like +# s=content() s.addElement(s) won't eat up too much processor time. + +odmimetypes = { + 'application/vnd.oasis.opendocument.text': '.odt', + 'application/vnd.oasis.opendocument.text-template': '.ott', + 'application/vnd.oasis.opendocument.graphics': '.odg', + 'application/vnd.oasis.opendocument.graphics-template': '.otg', + 'application/vnd.oasis.opendocument.presentation': '.odp', + 'application/vnd.oasis.opendocument.presentation-template': '.otp', + 'application/vnd.oasis.opendocument.spreadsheet': '.ods', + 'application/vnd.oasis.opendocument.spreadsheet-template': '.ots', + 'application/vnd.oasis.opendocument.chart': '.odc', + 'application/vnd.oasis.opendocument.chart-template': '.otc', + 'application/vnd.oasis.opendocument.image': '.odi', + 'application/vnd.oasis.opendocument.image-template': '.oti', + 'application/vnd.oasis.opendocument.formula': '.odf', + 'application/vnd.oasis.opendocument.formula-template': '.otf', + 'application/vnd.oasis.opendocument.text-master': '.odm', + 'application/vnd.oasis.opendocument.text-web': '.oth', +} + +class OpenDocument: + """ A class to hold the content of an OpenDocument document + Use the xml method to write the XML + source to the screen or to a file + d = OpenDocument(mimetype) + fd.write(d.xml()) + """ + thumbnail = None + + def __init__(self, mimetype, add_generator=True): + self.mimetype = mimetype + self.childobjects = [] + self.folder = "" # Always empty for toplevel documents + self.topnode = Document(mimetype=self.mimetype) + self.topnode.ownerDocument = self + + self.clear_caches() + + self.Pictures = {} + self.meta = Meta() + self.topnode.addElement(self.meta) + if add_generator: + self.meta.addElement(meta.Generator(text=TOOLSVERSION)) + self.scripts = Scripts() + self.topnode.addElement(self.scripts) + self.fontfacedecls = FontFaceDecls() + self.topnode.addElement(self.fontfacedecls) + self.settings = Settings() + self.topnode.addElement(self.settings) + self.styles = Styles() + self.topnode.addElement(self.styles) + self.automaticstyles = AutomaticStyles() + self.topnode.addElement(self.automaticstyles) + self.masterstyles = MasterStyles() + self.topnode.addElement(self.masterstyles) + self.body = Body() + self.topnode.addElement(self.body) + + def rebuild_caches(self, node=None): + if node is None: node = self.topnode + self.build_caches(node) + for e in node.childNodes: + if e.nodeType == element.Node.ELEMENT_NODE: + self.rebuild_caches(e) + + def clear_caches(self): + self.element_dict = {} + self._styles_dict = {} + self._styles_ooo_fix = {} + + def build_caches(self, element): + """ Called from element.py + """ + if not self.element_dict.has_key(element.qname): + self.element_dict[element.qname] = [] + self.element_dict[element.qname].append(element) + if element.qname == (STYLENS, u'style'): + self._register_stylename(element) # Add to style dictionary + styleref = element.getAttrNS(TEXTNS,u'style-name') + if styleref is not None and self._styles_ooo_fix.has_key(styleref): + element.setAttrNS(TEXTNS,u'style-name', self._styles_ooo_fix[styleref]) + + def _register_stylename(self, element): + ''' Register a style. But there are three style dictionaries: + office:styles, office:automatic-styles and office:master-styles + Chapter 14 + ''' + name = element.getAttrNS(STYLENS, u'name') + if name is None: + return + if element.parentNode.qname in ((OFFICENS,u'styles'), (OFFICENS,u'automatic-styles')): + if self._styles_dict.has_key(name): + newname = 'M'+name # Rename style + self._styles_ooo_fix[name] = newname + # From here on all references to the old name will refer to the new one + name = newname + element.setAttrNS(STYLENS, u'name', name) + self._styles_dict[name] = element + + def toXml(self, filename=''): + xml=StringIO() + xml.write(_XMLPROLOGUE) + self.body.toXml(0, xml) + if not filename: + return xml.getvalue() + else: + f=file(filename,'w') + f.write(xml.getvalue()) + f.close() + + def xml(self): + """ Generates the full document as an XML file + Always written as a bytestream in UTF-8 encoding + """ + self._replaceGenerator() + xml=StringIO() + xml.write(_XMLPROLOGUE) + self.topnode.toXml(0, xml) + return xml.getvalue() + + + def contentxml(self): + """ Generates the content.xml file + Always written as a bytestream in UTF-8 encoding + """ + xml=StringIO() + xml.write(_XMLPROLOGUE) + x = DocumentContent() + x.write_open_tag(0, xml) + if self.scripts.hasChildNodes(): + self.scripts.toXml(1, xml) + if self.fontfacedecls.hasChildNodes(): + self.fontfacedecls.toXml(1, xml) + a = AutomaticStyles() + stylelist = self._used_auto_styles([self.styles, self.body]) + if len(stylelist) > 0: + a.write_open_tag(1, xml) + for s in stylelist: + s.toXml(2, xml) + a.write_close_tag(1, xml) + else: + a.toXml(1, xml) + self.body.toXml(1, xml) + x.write_close_tag(0, xml) + return xml.getvalue() + + def manifestxml(self): + """ Generates the manifest.xml file """ + xml=StringIO() + xml.write(_XMLPROLOGUE) + self.manifest.toXml(0,xml) + return xml.getvalue() + + def metaxml(self): + """ Generates the meta.xml file """ + self._replaceGenerator() + x = DocumentMeta() + x.addElement(self.meta) + xml=StringIO() + xml.write(_XMLPROLOGUE) + x.toXml(0,xml) + return xml.getvalue() + + def settingsxml(self): + """ Generates the settings.xml file """ + x = DocumentSettings() + x.addElement(self.settings) + xml=StringIO() + xml.write(_XMLPROLOGUE) + x.toXml(0,xml) + return xml.getvalue() + + def _parseoneelement(self, top, stylenamelist): + """ Finds references to style objects in master-styles + and add the style name to the style list if not already there. + Recursive + """ + for e in top.childNodes: + if e.nodeType == element.Node.ELEMENT_NODE: + for styleref in ( (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (PRESENTATIONNS,u'style-name'), + (STYLENS,u'style-name'), + (STYLENS,u'list-style-name'), + (STYLENS,u'page-layout-name'), + (TABLENS,u'style-name'), + (TEXTNS,u'style-name') ): + if e.getAttrNS(styleref[0],styleref[1]): + stylename = e.getAttrNS(styleref[0],styleref[1]) + if stylename not in stylenamelist: + stylenamelist.append(stylename) + stylenamelist = self._parseoneelement(e, stylenamelist) + return stylenamelist + + def _used_auto_styles(self, segments): + """ Loop through the masterstyles elements, and find the automatic + styles that are used. These will be added to the automatic-styles + element in styles.xml + """ + stylenamelist = [] + for top in segments: + stylenamelist = self._parseoneelement(top, stylenamelist) + stylelist = [] + for e in self.automaticstyles.childNodes: + if e.getAttrNS(STYLENS,u'name') in stylenamelist: + stylelist.append(e) + return stylelist + + def stylesxml(self): + """ Generates the styles.xml file """ + xml=StringIO() + xml.write(_XMLPROLOGUE) + x = DocumentStyles() + x.write_open_tag(0, xml) + if self.fontfacedecls.hasChildNodes(): + self.fontfacedecls.toXml(1, xml) + self.styles.toXml(1, xml) + a = AutomaticStyles() + a.write_open_tag(1, xml) + for s in self._used_auto_styles([self.masterstyles]): + s.toXml(2, xml) + a.write_close_tag(1, xml) + if self.masterstyles.hasChildNodes(): + self.masterstyles.toXml(1, xml) + x.write_close_tag(0, xml) + return xml.getvalue() + + def addPicture(self, filename, mediatype=None, content=None): + """ Add a picture + It uses the same convention as OOo, in that it saves the picture in + the zipfile in the subdirectory 'Pictures' + If passed a file ptr, mediatype must be set + """ + if content is None: + if mediatype is None: + mediatype, encoding = mimetypes.guess_type(filename) + if mediatype is None: + mediatype = '' + try: ext = filename[filename.rindex('.'):] + except: ext='' + else: + ext = mimetypes.guess_extension(mediatype) + manifestfn = "Pictures/%0.0f%s" % ((time.time()*10000000000), ext) + self.Pictures[manifestfn] = (IS_FILENAME, fileobj, mediatype) + else: + manifestfn = filename + self.Pictures[manifestfn] = (IS_IMAGE, content, mediatype) + return manifestfn + + def addThumbnail(self, filecontent=None): + """ Add a fixed thumbnail + The thumbnail in the library is big, so this is pretty useless. + """ + if filecontent is None: + import thumbnail + self.thumbnail = thumbnail.thumbnail() + else: + self.thumbnail = filecontent + + def addObject(self, document): + """ Add an object. The object must be an OpenDocument class + The return value will be the folder in the zipfile the object is stored in + """ + self.childobjects.append(document) + document.folder = "%s/Object %d" % (self.folder, len(self.childobjects)) + return ".%s" % document.folder + + def _savePictures(self, object, folder): + hasPictures = False + for arcname, picturerec in object.Pictures.items(): + what_it_is, fileobj, mediatype = picturerec + self.manifest.addElement(manifest.FileEntry(fullpath="%s%s" % ( folder ,arcname), mediatype=mediatype)) + hasPictures = True + if what_it_is == IS_FILENAME: + self._z.write(fileobj, arcname, zipfile.ZIP_STORED) + else: + zi = zipfile.ZipInfo(str(arcname), self._now) + zi.compress_type = zipfile.ZIP_STORED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, fileobj) + if hasPictures: + self.manifest.addElement(manifest.FileEntry(fullpath="%sPictures/" % folder,mediatype="")) + # Look in subobjects + subobjectnum = 1 + for subobject in object.childobjects: + self._savePictures(subobject,'%sObject %d/' % (folder, subobjectnum)) + subobjectnum += 1 + + def _replaceGenerator(self): + """ Section 3.1.1: The application MUST NOT export the original identifier + belonging to the application that created the document. + """ + for m in self.meta.childNodes[:]: + if m.qname == (METANS, u'generator'): + self.meta.removeChild(m) + self.meta.addElement(meta.Generator(text=TOOLSVERSION)) + + def save(self, outputfile, addsuffix=False): + """ Save the document under the filename """ + if outputfile == '-': + outputfp = zipfile.ZipFile(sys.stdout,"w") + else: + if addsuffix: + outputfile = outputfile + odmimetypes.get(self.mimetype,'.xxx') + outputfp = zipfile.ZipFile(outputfile,"w") + self._zipwrite(outputfp) + outputfp.close() + + def write(self, outputfp): + zipoutputfp = zipfile.ZipFile(outputfp,"w") + self._zipwrite(zipoutputfp) + + def _zipwrite(self, outputfp): + """ Write the document to an open file pointer """ + self._z = outputfp + self._now = time.localtime()[:6] + self.manifest = manifest.Manifest() + + # Write mimetype + zi = zipfile.ZipInfo('mimetype', self._now) + zi.compress_type = zipfile.ZIP_STORED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, self.mimetype) + + self._saveXmlObjects(self,"") + + # Write pictures + self._savePictures(self,"") + + # Write the thumbnail + if self.thumbnail is not None: + self.manifest.addElement(manifest.FileEntry(fullpath="Thumbnails/", mediatype='')) + self.manifest.addElement(manifest.FileEntry(fullpath="Thumbnails/thumbnail.png", mediatype='')) + zi = zipfile.ZipInfo("Thumbnails/thumbnail.png", self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, self.thumbnail) + + # Write manifest + zi = zipfile.ZipInfo("META-INF/manifest.xml", self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, self.manifestxml() ) + del self._z + del self._now + del self.manifest + + + def _saveXmlObjects(self, object, folder): + if self == object: + self.manifest.addElement(manifest.FileEntry(fullpath="/", mediatype=object.mimetype)) + else: + self.manifest.addElement(manifest.FileEntry(fullpath=folder, mediatype=object.mimetype)) + # Write styles + self.manifest.addElement(manifest.FileEntry(fullpath="%sstyles.xml" % folder, mediatype="text/xml")) + zi = zipfile.ZipInfo("%sstyles.xml" % folder, self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, object.stylesxml() ) + + # Write content + self.manifest.addElement(manifest.FileEntry(fullpath="%scontent.xml" % folder, mediatype="text/xml")) + zi = zipfile.ZipInfo("%scontent.xml" % folder, self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, object.contentxml() ) + + # Write settings + if self == object and self.settings.hasChildNodes(): + self.manifest.addElement(manifest.FileEntry(fullpath="settings.xml",mediatype="text/xml")) + zi = zipfile.ZipInfo("%ssettings.xml" % folder, self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, object.settingsxml() ) + + # Write meta + if self == object: + self.manifest.addElement(manifest.FileEntry(fullpath="meta.xml",mediatype="text/xml")) + zi = zipfile.ZipInfo("meta.xml", self._now) + zi.compress_type = zipfile.ZIP_DEFLATED + zi.external_attr = UNIXPERMS + self._z.writestr(zi, object.metaxml() ) + + # Write subobjects + subobjectnum = 1 + for subobject in object.childobjects: + self._saveXmlObjects(subobject, '%sObject %d/' % (folder, subobjectnum)) + subobjectnum += 1 + +# Document's DOM methods + def createElement(self, element): + """ Inconvenient interface to create an element, but follows XML-DOM. + Does not allow attributes as argument, therefore can't check grammar. + """ + return element(check_grammar=False) + + def createTextNode(self, data): + """ Method to create a text node """ + return element.Text(data) + + def createCDATASection(self, data): + return element.CDATASection(cdata) + + def getMediaType(self): + """ Returns the media type """ + return self.mimetype + + def getStyleByName(self, name): + ncname = make_NCName(name) + if self._styles_dict == {}: + self.rebuild_caches() + return self._styles_dict.get(ncname, None) + + def getElementsByType(self, element): + obj = element(check_grammar=False) + if self.element_dict == {}: + self.rebuild_caches() + return self.element_dict.get(obj.qname, []) + +# Convenience functions +def OpenDocumentChart(): + doc = OpenDocument('application/vnd.oasis.opendocument.chart') + doc.chart = Chart() + doc.body.addElement(doc.chart) + return doc + +def OpenDocumentDrawing(): + doc = OpenDocument('application/vnd.oasis.opendocument.graphics') + doc.drawing = Drawing() + doc.body.addElement(doc.drawing) + return doc + +def OpenDocumentImage(): + doc = OpenDocument('application/vnd.oasis.opendocument.image') + doc.image = Image() + doc.body.addElement(doc.image) + return doc + +def OpenDocumentPresentation(): + doc = OpenDocument('application/vnd.oasis.opendocument.presentation') + doc.presentation = Presentation() + doc.body.addElement(doc.presentation) + return doc + +def OpenDocumentSpreadsheet(): + doc = OpenDocument('application/vnd.oasis.opendocument.spreadsheet') + doc.spreadsheet = Spreadsheet() + doc.body.addElement(doc.spreadsheet) + return doc + +def OpenDocumentText(): + doc = OpenDocument('application/vnd.oasis.opendocument.text') + doc.text = Text() + doc.body.addElement(doc.text) + return doc + + +def load(odffile): + from load import LoadParser + from xml.sax import make_parser, handler + z = zipfile.ZipFile(odffile) + mimetype = z.read('mimetype') + doc = OpenDocument(mimetype, add_generator=False) + + # Look in the manifest file to see if which of the four files there are + manifestpart = z.read('META-INF/manifest.xml') + manifest = manifestlist(manifestpart) + for xmlfile in ('settings.xml', 'meta.xml', 'content.xml', 'styles.xml'): + if not manifest.has_key(xmlfile): + continue + try: + xmlpart = z.read(xmlfile) + doc._parsing = xmlfile + + parser = make_parser() + parser.setFeature(handler.feature_namespaces, 1) + parser.setContentHandler(LoadParser(doc)) + parser.setErrorHandler(handler.ErrorHandler()) + + inpsrc = InputSource() + inpsrc.setByteStream(StringIO(xmlpart)) + parser.parse(inpsrc) + del doc._parsing + except KeyError, v: pass + # Add the thumbnail here + # Add the images here + for mentry,mvalue in manifest.items(): + if mentry[:9] == "Pictures/" and len(mentry) > 9: + doc.addPicture(mvalue['full-path'], mvalue['media-type'], z.read(mentry)) + elif mentry == "Thumbnails/thumbnail.png": + doc.addThumbnail(z.read(mentry)) + else: + pass # Add the SUN junk here to the struct somewhere + # It is cached data, so it can be out-of-date + z.close() + b = doc.getElementsByType(Body) + if mimetype[:39] == 'application/vnd.oasis.opendocument.text': + doc.text = b[0].firstChild + elif mimetype[:43] == 'application/vnd.oasis.opendocument.graphics': + doc.graphics = b[0].firstChild + elif mimetype[:47] == 'application/vnd.oasis.opendocument.presentation': + doc.presentation = b[0].firstChild + elif mimetype[:46] == 'application/vnd.oasis.opendocument.spreadsheet': + doc.spreadsheet = b[0].firstChild + elif mimetype[:40] == 'application/vnd.oasis.opendocument.chart': + doc.chart = b[0].firstChild + elif mimetype[:40] == 'application/vnd.oasis.opendocument.image': + doc.image = b[0].firstChild + elif mimetype[:42] == 'application/vnd.oasis.opendocument.formula': + doc.formula = b[0].firstChild + return doc +# vim: set expandtab sw=4 : diff --git a/src/odf/presentation.py b/src/odf/presentation.py new file mode 100644 index 0000000000..c1f2135abb --- /dev/null +++ b/src/odf/presentation.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import PRESENTATIONNS +from element import Element + +# ODF 1.0 section 9.6 and 9.7 +# Autogenerated +def AnimationGroup(**args): + return Element(qname = (PRESENTATIONNS,'animation-group'), **args) + +def Animations(**args): + return Element(qname = (PRESENTATIONNS,'animations'), **args) + +def DateTime(**args): + return Element(qname = (PRESENTATIONNS,'date-time'), **args) + +def DateTimeDecl(**args): + return Element(qname = (PRESENTATIONNS,'date-time-decl'), **args) + +def Dim(**args): + return Element(qname = (PRESENTATIONNS,'dim'), **args) + +def EventListener(**args): + return Element(qname = (PRESENTATIONNS,'event-listener'), **args) + +def Footer(**args): + return Element(qname = (PRESENTATIONNS,'footer'), **args) + +def FooterDecl(**args): + return Element(qname = (PRESENTATIONNS,'footer-decl'), **args) + +def Header(**args): + return Element(qname = (PRESENTATIONNS,'header'), **args) + +def HeaderDecl(**args): + return Element(qname = (PRESENTATIONNS,'header-decl'), **args) + +def HideShape(**args): + return Element(qname = (PRESENTATIONNS,'hide-shape'), **args) + +def HideText(**args): + return Element(qname = (PRESENTATIONNS,'hide-text'), **args) + +def Notes(**args): + return Element(qname = (PRESENTATIONNS,'notes'), **args) + +def Placeholder(**args): + return Element(qname = (PRESENTATIONNS,'placeholder'), **args) + +def Play(**args): + return Element(qname = (PRESENTATIONNS,'play'), **args) + +def Settings(**args): + return Element(qname = (PRESENTATIONNS,'settings'), **args) + +def Show(**args): + return Element(qname = (PRESENTATIONNS,'show'), **args) + +def ShowShape(**args): + return Element(qname = (PRESENTATIONNS,'show-shape'), **args) + +def ShowText(**args): + return Element(qname = (PRESENTATIONNS,'show-text'), **args) + +def Sound(**args): + return Element(qname = (PRESENTATIONNS,'sound'), **args) + diff --git a/src/odf/script.py b/src/odf/script.py new file mode 100644 index 0000000000..adbc73f657 --- /dev/null +++ b/src/odf/script.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import SCRIPTNS +from element import Element + +# ODF 1.0 section 12.4.1 +# The element binds an event to a macro. + +# Autogenerated +def EventListener(**args): + return Element(qname = (SCRIPTNS,'event-listener'), **args) + diff --git a/src/odf/style.py b/src/odf/style.py new file mode 100644 index 0000000000..f64d7c8217 --- /dev/null +++ b/src/odf/style.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import STYLENS +from element import Element + +def StyleElement(**args): + e = Element(**args) + if args.get('check_grammar', True) == True: + if not args.has_key('displayname'): + e.setAttrNS(STYLENS,'display-name', args.get('name')) + return e + +# Autogenerated +def BackgroundImage(**args): + return Element(qname = (STYLENS,'background-image'), **args) + +def ChartProperties(**args): + return Element(qname = (STYLENS,'chart-properties'), **args) + +def Column(**args): + return Element(qname = (STYLENS,'column'), **args) + +def ColumnSep(**args): + return Element(qname = (STYLENS,'column-sep'), **args) + +def Columns(**args): + return Element(qname = (STYLENS,'columns'), **args) + +def DefaultStyle(**args): + return Element(qname = (STYLENS,'default-style'), **args) + +def DrawingPageProperties(**args): + return Element(qname = (STYLENS,'drawing-page-properties'), **args) + +def DropCap(**args): + return Element(qname = (STYLENS,'drop-cap'), **args) + +def FontFace(**args): + return Element(qname = (STYLENS,'font-face'), **args) + +def Footer(**args): + return Element(qname = (STYLENS,'footer'), **args) + +def FooterLeft(**args): + return Element(qname = (STYLENS,'footer-left'), **args) + +def FooterStyle(**args): + return Element(qname = (STYLENS,'footer-style'), **args) + +def FootnoteSep(**args): + return Element(qname = (STYLENS,'footnote-sep'), **args) + +def GraphicProperties(**args): + return Element(qname = (STYLENS,'graphic-properties'), **args) + +def HandoutMaster(**args): + return Element(qname = (STYLENS,'handout-master'), **args) + +def Header(**args): + return Element(qname = (STYLENS,'header'), **args) + +def HeaderFooterProperties(**args): + return Element(qname = (STYLENS,'header-footer-properties'), **args) + +def HeaderLeft(**args): + return Element(qname = (STYLENS,'header-left'), **args) + +def HeaderStyle(**args): + return Element(qname = (STYLENS,'header-style'), **args) + +def ListLevelProperties(**args): + return Element(qname = (STYLENS,'list-level-properties'), **args) + +def Map(**args): + return Element(qname = (STYLENS,'map'), **args) + +def MasterPage(**args): + return StyleElement(qname = (STYLENS,'master-page'), **args) + +def PageLayout(**args): + return Element(qname = (STYLENS,'page-layout'), **args) + +def PageLayoutProperties(**args): + return Element(qname = (STYLENS,'page-layout-properties'), **args) + +def ParagraphProperties(**args): + return Element(qname = (STYLENS,'paragraph-properties'), **args) + +def PresentationPageLayout(**args): + return StyleElement(qname = (STYLENS,'presentation-page-layout'), **args) + +def RegionCenter(**args): + return Element(qname = (STYLENS,'region-center'), **args) + +def RegionLeft(**args): + return Element(qname = (STYLENS,'region-left'), **args) + +def RegionRight(**args): + return Element(qname = (STYLENS,'region-right'), **args) + +def RubyProperties(**args): + return Element(qname = (STYLENS,'ruby-properties'), **args) + +def SectionProperties(**args): + return Element(qname = (STYLENS,'section-properties'), **args) + +def Style(**args): + return StyleElement(qname = (STYLENS,'style'), **args) + +def TabStop(**args): + return Element(qname = (STYLENS,'tab-stop'), **args) + +def TabStops(**args): + return Element(qname = (STYLENS,'tab-stops'), **args) + +def TableCellProperties(**args): + return Element(qname = (STYLENS,'table-cell-properties'), **args) + +def TableColumnProperties(**args): + return Element(qname = (STYLENS,'table-column-properties'), **args) + +def TableProperties(**args): + return Element(qname = (STYLENS,'table-properties'), **args) + +def TableRowProperties(**args): + return Element(qname = (STYLENS,'table-row-properties'), **args) + +def TextProperties(**args): + return Element(qname = (STYLENS,'text-properties'), **args) + diff --git a/src/odf/svg.py b/src/odf/svg.py new file mode 100644 index 0000000000..e53d54001e --- /dev/null +++ b/src/odf/svg.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import SVGNS +from element import Element +from draw import DrawElement + +# Autogenerated +def DefinitionSrc(**args): + return Element(qname = (SVGNS,'definition-src'), **args) + +def Desc(**args): + return Element(qname = (SVGNS,'desc'), **args) + +def FontFaceFormat(**args): + return Element(qname = (SVGNS,'font-face-format'), **args) + +def FontFaceName(**args): + return Element(qname = (SVGNS,'font-face-name'), **args) + +def FontFaceSrc(**args): + return Element(qname = (SVGNS,'font-face-src'), **args) + +def FontFaceUri(**args): + return Element(qname = (SVGNS,'font-face-uri'), **args) + +def Lineargradient(**args): + return DrawElement(qname = (SVGNS,'linearGradient'), **args) + +def Radialgradient(**args): + return DrawElement(qname = (SVGNS,'radialGradient'), **args) + +def Stop(**args): + return Element(qname = (SVGNS,'stop'), **args) + diff --git a/src/odf/table.py b/src/odf/table.py new file mode 100644 index 0000000000..4ba0c36e9b --- /dev/null +++ b/src/odf/table.py @@ -0,0 +1,307 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import TABLENS +from element import Element + + +# Autogenerated +def Body(**args): + return Element(qname = (TABLENS,'body'), **args) + +def CalculationSettings(**args): + return Element(qname = (TABLENS,'calculation-settings'), **args) + +def CellAddress(**args): + return Element(qname = (TABLENS,'cell-address'), **args) + +def CellContentChange(**args): + return Element(qname = (TABLENS,'cell-content-change'), **args) + +def CellContentDeletion(**args): + return Element(qname = (TABLENS,'cell-content-deletion'), **args) + +def CellRangeSource(**args): + return Element(qname = (TABLENS,'cell-range-source'), **args) + +def ChangeDeletion(**args): + return Element(qname = (TABLENS,'change-deletion'), **args) + +def ChangeTrackTableCell(**args): + return Element(qname = (TABLENS,'change-track-table-cell'), **args) + +def Consolidation(**args): + return Element(qname = (TABLENS,'consolidation'), **args) + +def ContentValidation(**args): + return Element(qname = (TABLENS,'content-validation'), **args) + +def ContentValidations(**args): + return Element(qname = (TABLENS,'content-validations'), **args) + +def CoveredTableCell(**args): + return Element(qname = (TABLENS,'covered-table-cell'), **args) + +def CutOffs(**args): + return Element(qname = (TABLENS,'cut-offs'), **args) + +def DataPilotDisplayInfo(**args): + return Element(qname = (TABLENS,'data-pilot-display-info'), **args) + +def DataPilotField(**args): + return Element(qname = (TABLENS,'data-pilot-field'), **args) + +def DataPilotFieldReference(**args): + return Element(qname = (TABLENS,'data-pilot-field-reference'), **args) + +def DataPilotGroup(**args): + return Element(qname = (TABLENS,'data-pilot-group'), **args) + +def DataPilotGroupMember(**args): + return Element(qname = (TABLENS,'data-pilot-group-member'), **args) + +def DataPilotGroups(**args): + return Element(qname = (TABLENS,'data-pilot-groups'), **args) + +def DataPilotLayoutInfo(**args): + return Element(qname = (TABLENS,'data-pilot-layout-info'), **args) + +def DataPilotLevel(**args): + return Element(qname = (TABLENS,'data-pilot-level'), **args) + +def DataPilotMember(**args): + return Element(qname = (TABLENS,'data-pilot-member'), **args) + +def DataPilotMembers(**args): + return Element(qname = (TABLENS,'data-pilot-members'), **args) + +def DataPilotSortInfo(**args): + return Element(qname = (TABLENS,'data-pilot-sort-info'), **args) + +def DataPilotSubtotal(**args): + return Element(qname = (TABLENS,'data-pilot-subtotal'), **args) + +def DataPilotSubtotals(**args): + return Element(qname = (TABLENS,'data-pilot-subtotals'), **args) + +def DataPilotTable(**args): + return Element(qname = (TABLENS,'data-pilot-table'), **args) + +def DataPilotTables(**args): + return Element(qname = (TABLENS,'data-pilot-tables'), **args) + +def DatabaseRange(**args): + return Element(qname = (TABLENS,'database-range'), **args) + +def DatabaseRanges(**args): + return Element(qname = (TABLENS,'database-ranges'), **args) + +def DatabaseSourceQuery(**args): + return Element(qname = (TABLENS,'database-source-query'), **args) + +def DatabaseSourceSql(**args): + return Element(qname = (TABLENS,'database-source-sql'), **args) + +def DatabaseSourceTable(**args): + return Element(qname = (TABLENS,'database-source-table'), **args) + +def DdeLink(**args): + return Element(qname = (TABLENS,'dde-link'), **args) + +def DdeLinks(**args): + return Element(qname = (TABLENS,'dde-links'), **args) + +def Deletion(**args): + return Element(qname = (TABLENS,'deletion'), **args) + +def Deletions(**args): + return Element(qname = (TABLENS,'deletions'), **args) + +def Dependencies(**args): + return Element(qname = (TABLENS,'dependencies'), **args) + +def Dependency(**args): + return Element(qname = (TABLENS,'dependency'), **args) + +def Detective(**args): + return Element(qname = (TABLENS,'detective'), **args) + +def ErrorMacro(**args): + return Element(qname = (TABLENS,'error-macro'), **args) + +def ErrorMessage(**args): + return Element(qname = (TABLENS,'error-message'), **args) + +def EvenColumns(**args): + return Element(qname = (TABLENS,'even-columns'), **args) + +def EvenRows(**args): + return Element(qname = (TABLENS,'even-rows'), **args) + +def Filter(**args): + return Element(qname = (TABLENS,'filter'), **args) + +def FilterAnd(**args): + return Element(qname = (TABLENS,'filter-and'), **args) + +def FilterCondition(**args): + return Element(qname = (TABLENS,'filter-condition'), **args) + +def FilterOr(**args): + return Element(qname = (TABLENS,'filter-or'), **args) + +def FirstColumn(**args): + return Element(qname = (TABLENS,'first-column'), **args) + +def FirstRow(**args): + return Element(qname = (TABLENS,'first-row'), **args) + +def HelpMessage(**args): + return Element(qname = (TABLENS,'help-message'), **args) + +def HighlightedRange(**args): + return Element(qname = (TABLENS,'highlighted-range'), **args) + +def Insertion(**args): + return Element(qname = (TABLENS,'insertion'), **args) + +def InsertionCutOff(**args): + return Element(qname = (TABLENS,'insertion-cut-off'), **args) + +def Iteration(**args): + return Element(qname = (TABLENS,'iteration'), **args) + +def LabelRange(**args): + return Element(qname = (TABLENS,'label-range'), **args) + +def LabelRanges(**args): + return Element(qname = (TABLENS,'label-ranges'), **args) + +def LastColumn(**args): + return Element(qname = (TABLENS,'last-column'), **args) + +def LastRow(**args): + return Element(qname = (TABLENS,'last-row'), **args) + +def Movement(**args): + return Element(qname = (TABLENS,'movement'), **args) + +def MovementCutOff(**args): + return Element(qname = (TABLENS,'movement-cut-off'), **args) + +def NamedExpression(**args): + return Element(qname = (TABLENS,'named-expression'), **args) + +def NamedExpressions(**args): + return Element(qname = (TABLENS,'named-expressions'), **args) + +def NamedRange(**args): + return Element(qname = (TABLENS,'named-range'), **args) + +def NullDate(**args): + return Element(qname = (TABLENS,'null-date'), **args) + +def OddColumns(**args): + return Element(qname = (TABLENS,'odd-columns'), **args) + +def OddRows(**args): + return Element(qname = (TABLENS,'odd-rows'), **args) + +def Operation(**args): + return Element(qname = (TABLENS,'operation'), **args) + +def Previous(**args): + return Element(qname = (TABLENS,'previous'), **args) + +def Scenario(**args): + return Element(qname = (TABLENS,'scenario'), **args) + +def Shapes(**args): + return Element(qname = (TABLENS,'shapes'), **args) + +def Sort(**args): + return Element(qname = (TABLENS,'sort'), **args) + +def SortBy(**args): + return Element(qname = (TABLENS,'sort-by'), **args) + +def SortGroups(**args): + return Element(qname = (TABLENS,'sort-groups'), **args) + +def SourceCellRange(**args): + return Element(qname = (TABLENS,'source-cell-range'), **args) + +def SourceRangeAddress(**args): + return Element(qname = (TABLENS,'source-range-address'), **args) + +def SourceService(**args): + return Element(qname = (TABLENS,'source-service'), **args) + +def SubtotalField(**args): + return Element(qname = (TABLENS,'subtotal-field'), **args) + +def SubtotalRule(**args): + return Element(qname = (TABLENS,'subtotal-rule'), **args) + +def SubtotalRules(**args): + return Element(qname = (TABLENS,'subtotal-rules'), **args) + +def Table(**args): + return Element(qname = (TABLENS,'table'), **args) + +def TableCell(**args): + return Element(qname = (TABLENS,'table-cell'), **args) + +def TableColumn(**args): + return Element(qname = (TABLENS,'table-column'), **args) + +def TableColumnGroup(**args): + return Element(qname = (TABLENS,'table-column-group'), **args) + +def TableColumns(**args): + return Element(qname = (TABLENS,'table-columns'), **args) + +def TableHeaderColumns(**args): + return Element(qname = (TABLENS,'table-header-columns'), **args) + +def TableHeaderRows(**args): + return Element(qname = (TABLENS,'table-header-rows'), **args) + +def TableRow(**args): + return Element(qname = (TABLENS,'table-row'), **args) + +def TableRowGroup(**args): + return Element(qname = (TABLENS,'table-row-group'), **args) + +def TableRows(**args): + return Element(qname = (TABLENS,'table-rows'), **args) + +def TableSource(**args): + return Element(qname = (TABLENS,'table-source'), **args) + +def TableTemplate(**args): + return Element(qname = (TABLENS,'table-template'), **args) + +def TargetRangeAddress(**args): + return Element(qname = (TABLENS,'target-range-address'), **args) + +def TrackedChanges(**args): + return Element(qname = (TABLENS,'tracked-changes'), **args) + diff --git a/src/odf/teletype.py b/src/odf/teletype.py new file mode 100644 index 0000000000..53b58fd469 --- /dev/null +++ b/src/odf/teletype.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# +# Create and extract text from ODF, handling whitespace correctly. +# Copyright (C) 2008 J. David Eisenberg +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +""" +Class for handling whitespace properly in OpenDocument. + +While it is possible to use getTextContent() and setTextContent() +to extract or create ODF content, these won't extract or create +the appropriate , , or +elements. This module takes care of that problem. +""" + +from odf.element import Node +import odf.opendocument +from odf.text import S,LineBreak,Tab + +class WhitespaceText(object): + + def __init__(self): + self.textBuffer = [] + self.spaceCount = 0 + + def addTextToElement(self, odfElement, s): + """ Process an input string, inserting + elements for '\t', + elements for '\n', and + elements for runs of more than one blank. + These will be added to the given element. + """ + i = 0 + ch = ' ' + + # When we encounter a tab or newline, we can immediately + # dump any accumulated text and then emit the appropriate + # ODF element. + # + # When we encounter a space, we add it to the text buffer, + # and then collect more spaces. If there are more spaces + # after the first one, we dump the text buffer and then + # then emit the appropriate element. + + while i < len(s): + ch = s[i] + if ch == '\t': + self._emitTextBuffer(odfElement) + odfElement.addElement(Tab()) + i += 1 + elif ch == '\n': + self._emitTextBuffer(odfElement); + odfElement.addElement(LineBreak()) + i += 1 + elif ch == ' ': + self.textBuffer.append(' ') + i += 1 + self.spaceCount = 0 + while i < len(s) and (s[i] == ' '): + self.spaceCount += 1 + i += 1 + if self.spaceCount > 0: + self._emitTextBuffer(odfElement) + self._emitSpaces(odfElement) + else: + self.textBuffer.append(ch) + i += 1 + + self._emitTextBuffer(odfElement) + + def _emitTextBuffer(self, odfElement): + """ Creates a Text Node whose contents are the current textBuffer. + Side effect: clears the text buffer. + """ + if len(self.textBuffer) > 0: + odfElement.addText(''.join(self.textBuffer)) + self.textBuffer = [] + + + def _emitSpaces(self, odfElement): + """ Creates a element for the current spaceCount. + Side effect: sets spaceCount back to zero + """ + if self.spaceCount > 0: + spaceElement = S(c=self.spaceCount) + odfElement.addElement(spaceElement) + self.spaceCount = 0 + +def addTextToElement(odfElement, s): + wst = WhitespaceText() + wst.addTextToElement(odfElement, s) + +def extractText(odfElement): + """ Extract text content from an Element, with whitespace represented + properly. Returns the text, with tabs, spaces, and newlines + correctly evaluated. This method recursively descends through the + children of the given element, accumulating text and "unwrapping" + , , and elements along the way. + """ + result = []; + + if len(odfElement.childNodes) != 0: + for child in odfElement.childNodes: + if child.nodeType == Node.TEXT_NODE: + result.append(child.data) + elif child.nodeType == Node.ELEMENT_NODE: + subElement = child + tagName = subElement.qname; + if tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"line-break"): + result.append("\n") + elif tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"tab"): + result.append("\t") + elif tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"s"): + c = subElement.getAttribute('c') + if c: + spaceCount = int(c) + else: + spaceCount = 1 + + result.append(" " * spaceCount) + else: + result.append(extractText(subElement)) + return ''.join(result) diff --git a/src/odf/text.py b/src/odf/text.py new file mode 100644 index 0000000000..13a2c9ca6d --- /dev/null +++ b/src/odf/text.py @@ -0,0 +1,559 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import TEXTNS +from element import Element +from style import StyleElement + +# Autogenerated +def A(**args): + return Element(qname = (TEXTNS,'a'), **args) + +def AlphabeticalIndex(**args): + return Element(qname = (TEXTNS,'alphabetical-index'), **args) + +def AlphabeticalIndexAutoMarkFile(**args): + return Element(qname = (TEXTNS,'alphabetical-index-auto-mark-file'), **args) + +def AlphabeticalIndexEntryTemplate(**args): + return Element(qname = (TEXTNS,'alphabetical-index-entry-template'), **args) + +def AlphabeticalIndexMark(**args): + return Element(qname = (TEXTNS,'alphabetical-index-mark'), **args) + +def AlphabeticalIndexMarkEnd(**args): + return Element(qname = (TEXTNS,'alphabetical-index-mark-end'), **args) + +def AlphabeticalIndexMarkStart(**args): + return Element(qname = (TEXTNS,'alphabetical-index-mark-start'), **args) + +def AlphabeticalIndexSource(**args): + return Element(qname = (TEXTNS,'alphabetical-index-source'), **args) + +def AuthorInitials(**args): + return Element(qname = (TEXTNS,'author-initials'), **args) + +def AuthorName(**args): + return Element(qname = (TEXTNS,'author-name'), **args) + +def Bibliography(**args): + return Element(qname = (TEXTNS,'bibliography'), **args) + +def BibliographyConfiguration(**args): + return Element(qname = (TEXTNS,'bibliography-configuration'), **args) + +def BibliographyEntryTemplate(**args): + return Element(qname = (TEXTNS,'bibliography-entry-template'), **args) + +def BibliographyMark(**args): + return Element(qname = (TEXTNS,'bibliography-mark'), **args) + +def BibliographySource(**args): + return Element(qname = (TEXTNS,'bibliography-source'), **args) + +def Bookmark(**args): + return Element(qname = (TEXTNS,'bookmark'), **args) + +def BookmarkEnd(**args): + return Element(qname = (TEXTNS,'bookmark-end'), **args) + +def BookmarkRef(**args): + return Element(qname = (TEXTNS,'bookmark-ref'), **args) + +def BookmarkStart(**args): + return Element(qname = (TEXTNS,'bookmark-start'), **args) + +def Change(**args): + return Element(qname = (TEXTNS,'change'), **args) + +def ChangeEnd(**args): + return Element(qname = (TEXTNS,'change-end'), **args) + +def ChangeStart(**args): + return Element(qname = (TEXTNS,'change-start'), **args) + +def ChangedRegion(**args): + return Element(qname = (TEXTNS,'changed-region'), **args) + +def Chapter(**args): + return Element(qname = (TEXTNS,'chapter'), **args) + +def CharacterCount(**args): + return Element(qname = (TEXTNS,'character-count'), **args) + +def ConditionalText(**args): + return Element(qname = (TEXTNS,'conditional-text'), **args) + +def CreationDate(**args): + return Element(qname = (TEXTNS,'creation-date'), **args) + +def CreationTime(**args): + return Element(qname = (TEXTNS,'creation-time'), **args) + +def Creator(**args): + return Element(qname = (TEXTNS,'creator'), **args) + +def DatabaseDisplay(**args): + return Element(qname = (TEXTNS,'database-display'), **args) + +def DatabaseName(**args): + return Element(qname = (TEXTNS,'database-name'), **args) + +def DatabaseNext(**args): + return Element(qname = (TEXTNS,'database-next'), **args) + +def DatabaseRowNumber(**args): + return Element(qname = (TEXTNS,'database-row-number'), **args) + +def DatabaseRowSelect(**args): + return Element(qname = (TEXTNS,'database-row-select'), **args) + +def Date(**args): + return Element(qname = (TEXTNS,'date'), **args) + +def DdeConnection(**args): + return Element(qname = (TEXTNS,'dde-connection'), **args) + +def DdeConnectionDecl(**args): + return Element(qname = (TEXTNS,'dde-connection-decl'), **args) + +def DdeConnectionDecls(**args): + return Element(qname = (TEXTNS,'dde-connection-decls'), **args) + +def Deletion(**args): + return Element(qname = (TEXTNS,'deletion'), **args) + +def Description(**args): + return Element(qname = (TEXTNS,'description'), **args) + +def EditingCycles(**args): + return Element(qname = (TEXTNS,'editing-cycles'), **args) + +def EditingDuration(**args): + return Element(qname = (TEXTNS,'editing-duration'), **args) + +def ExecuteMacro(**args): + return Element(qname = (TEXTNS,'execute-macro'), **args) + +def Expression(**args): + return Element(qname = (TEXTNS,'expression'), **args) + +def FileName(**args): + return Element(qname = (TEXTNS,'file-name'), **args) + +def FormatChange(**args): + return Element(qname = (TEXTNS,'format-change'), **args) + +def H(**args): + return Element(qname = (TEXTNS, 'h'), **args) + +def HiddenParagraph(**args): + return Element(qname = (TEXTNS,'hidden-paragraph'), **args) + +def HiddenText(**args): + return Element(qname = (TEXTNS,'hidden-text'), **args) + +def IllustrationIndex(**args): + return Element(qname = (TEXTNS,'illustration-index'), **args) + +def IllustrationIndexEntryTemplate(**args): + return Element(qname = (TEXTNS,'illustration-index-entry-template'), **args) + +def IllustrationIndexSource(**args): + return Element(qname = (TEXTNS,'illustration-index-source'), **args) + +def ImageCount(**args): + return Element(qname = (TEXTNS,'image-count'), **args) + +def IndexBody(**args): + return Element(qname = (TEXTNS,'index-body'), **args) + +def IndexEntryBibliography(**args): + return Element(qname = (TEXTNS,'index-entry-bibliography'), **args) + +def IndexEntryChapter(**args): + return Element(qname = (TEXTNS,'index-entry-chapter'), **args) + +def IndexEntryLinkEnd(**args): + return Element(qname = (TEXTNS,'index-entry-link-end'), **args) + +def IndexEntryLinkStart(**args): + return Element(qname = (TEXTNS,'index-entry-link-start'), **args) + +def IndexEntryPageNumber(**args): + return Element(qname = (TEXTNS,'index-entry-page-number'), **args) + +def IndexEntrySpan(**args): + return Element(qname = (TEXTNS,'index-entry-span'), **args) + +def IndexEntryTabStop(**args): + return Element(qname = (TEXTNS,'index-entry-tab-stop'), **args) + +def IndexEntryText(**args): + return Element(qname = (TEXTNS,'index-entry-text'), **args) + +def IndexSourceStyle(**args): + return Element(qname = (TEXTNS,'index-source-style'), **args) + +def IndexSourceStyles(**args): + return Element(qname = (TEXTNS,'index-source-styles'), **args) + +def IndexTitle(**args): + return Element(qname = (TEXTNS,'index-title'), **args) + +def IndexTitleTemplate(**args): + return Element(qname = (TEXTNS,'index-title-template'), **args) + +def InitialCreator(**args): + return Element(qname = (TEXTNS,'initial-creator'), **args) + +def Insertion(**args): + return Element(qname = (TEXTNS,'insertion'), **args) + +def Keywords(**args): + return Element(qname = (TEXTNS,'keywords'), **args) + +def LineBreak(**args): + return Element(qname = (TEXTNS,'line-break'), **args) + +def LinenumberingConfiguration(**args): + return Element(qname = (TEXTNS,'linenumbering-configuration'), **args) + +def LinenumberingSeparator(**args): + return Element(qname = (TEXTNS,'linenumbering-separator'), **args) + +def List(**args): + return Element(qname = (TEXTNS,'list'), **args) + +def ListHeader(**args): + return Element(qname = (TEXTNS,'list-header'), **args) + +def ListItem(**args): + return Element(qname = (TEXTNS,'list-item'), **args) + +def ListLevelStyleBullet(**args): + return Element(qname = (TEXTNS,'list-level-style-bullet'), **args) + +def ListLevelStyleImage(**args): + return Element(qname = (TEXTNS,'list-level-style-image'), **args) + +def ListLevelStyleNumber(**args): + return Element(qname = (TEXTNS,'list-level-style-number'), **args) + +def ListStyle(**args): + return StyleElement(qname = (TEXTNS,'list-style'), **args) + +def Measure(**args): + return Element(qname = (TEXTNS,'measure'), **args) + +def ModificationDate(**args): + return Element(qname = (TEXTNS,'modification-date'), **args) + +def ModificationTime(**args): + return Element(qname = (TEXTNS,'modification-time'), **args) + +def Note(**args): + return Element(qname = (TEXTNS,'note'), **args) + +def NoteBody(**args): + return Element(qname = (TEXTNS,'note-body'), **args) + +def NoteCitation(**args): + return Element(qname = (TEXTNS,'note-citation'), **args) + +def NoteContinuationNoticeBackward(**args): + return Element(qname = (TEXTNS,'note-continuation-notice-backward'), **args) + +def NoteContinuationNoticeForward(**args): + return Element(qname = (TEXTNS,'note-continuation-notice-forward'), **args) + +def NoteRef(**args): + return Element(qname = (TEXTNS,'note-ref'), **args) + +def NotesConfiguration(**args): + return Element(qname = (TEXTNS,'notes-configuration'), **args) + +def Number(**args): + return Element(qname = (TEXTNS,'number'), **args) + +def NumberedParagraph(**args): + return Element(qname = (TEXTNS,'numbered-paragraph'), **args) + +def ObjectCount(**args): + return Element(qname = (TEXTNS,'object-count'), **args) + +def ObjectIndex(**args): + return Element(qname = (TEXTNS,'object-index'), **args) + +def ObjectIndexEntryTemplate(**args): + return Element(qname = (TEXTNS,'object-index-entry-template'), **args) + +def ObjectIndexSource(**args): + return Element(qname = (TEXTNS,'object-index-source'), **args) + +def OutlineLevelStyle(**args): + return Element(qname = (TEXTNS,'outline-level-style'), **args) + +def OutlineStyle(**args): + return Element(qname = (TEXTNS,'outline-style'), **args) + +def P(**args): + return Element(qname = (TEXTNS, 'p'), **args) + +def Page(**args): + return Element(qname = (TEXTNS,'page'), **args) + +def PageContinuation(**args): + return Element(qname = (TEXTNS,'page-continuation'), **args) + +def PageCount(**args): + return Element(qname = (TEXTNS,'page-count'), **args) + +def PageNumber(**args): + return Element(qname = (TEXTNS,'page-number'), **args) + +def PageSequence(**args): + return Element(qname = (TEXTNS,'page-sequence'), **args) + +def PageVariableGet(**args): + return Element(qname = (TEXTNS,'page-variable-get'), **args) + +def PageVariableSet(**args): + return Element(qname = (TEXTNS,'page-variable-set'), **args) + +def ParagraphCount(**args): + return Element(qname = (TEXTNS,'paragraph-count'), **args) + +def Placeholder(**args): + return Element(qname = (TEXTNS,'placeholder'), **args) + +def PrintDate(**args): + return Element(qname = (TEXTNS,'print-date'), **args) + +def PrintTime(**args): + return Element(qname = (TEXTNS,'print-time'), **args) + +def PrintedBy(**args): + return Element(qname = (TEXTNS,'printed-by'), **args) + +def ReferenceMark(**args): + return Element(qname = (TEXTNS,'reference-mark'), **args) + +def ReferenceMarkEnd(**args): + return Element(qname = (TEXTNS,'reference-mark-end'), **args) + +def ReferenceMarkStart(**args): + return Element(qname = (TEXTNS,'reference-mark-start'), **args) + +def ReferenceRef(**args): + return Element(qname = (TEXTNS,'reference-ref'), **args) + +def Ruby(**args): + return Element(qname = (TEXTNS,'ruby'), **args) + +def RubyBase(**args): + return Element(qname = (TEXTNS,'ruby-base'), **args) + +def RubyText(**args): + return Element(qname = (TEXTNS,'ruby-text'), **args) + +def S(**args): + return Element(qname = (TEXTNS,'s'), **args) + +def Script(**args): + return Element(qname = (TEXTNS,'script'), **args) + +def Section(**args): + return Element(qname = (TEXTNS,'section'), **args) + +def SectionSource(**args): + return Element(qname = (TEXTNS,'section-source'), **args) + +def SenderCity(**args): + return Element(qname = (TEXTNS,'sender-city'), **args) + +def SenderCompany(**args): + return Element(qname = (TEXTNS,'sender-company'), **args) + +def SenderCountry(**args): + return Element(qname = (TEXTNS,'sender-country'), **args) + +def SenderEmail(**args): + return Element(qname = (TEXTNS,'sender-email'), **args) + +def SenderFax(**args): + return Element(qname = (TEXTNS,'sender-fax'), **args) + +def SenderFirstname(**args): + return Element(qname = (TEXTNS,'sender-firstname'), **args) + +def SenderInitials(**args): + return Element(qname = (TEXTNS,'sender-initials'), **args) + +def SenderLastname(**args): + return Element(qname = (TEXTNS,'sender-lastname'), **args) + +def SenderPhonePrivate(**args): + return Element(qname = (TEXTNS,'sender-phone-private'), **args) + +def SenderPhoneWork(**args): + return Element(qname = (TEXTNS,'sender-phone-work'), **args) + +def SenderPosition(**args): + return Element(qname = (TEXTNS,'sender-position'), **args) + +def SenderPostalCode(**args): + return Element(qname = (TEXTNS,'sender-postal-code'), **args) + +def SenderStateOrProvince(**args): + return Element(qname = (TEXTNS,'sender-state-or-province'), **args) + +def SenderStreet(**args): + return Element(qname = (TEXTNS,'sender-street'), **args) + +def SenderTitle(**args): + return Element(qname = (TEXTNS,'sender-title'), **args) + +def Sequence(**args): + return Element(qname = (TEXTNS,'sequence'), **args) + +def SequenceDecl(**args): + return Element(qname = (TEXTNS,'sequence-decl'), **args) + +def SequenceDecls(**args): + return Element(qname = (TEXTNS,'sequence-decls'), **args) + +def SequenceRef(**args): + return Element(qname = (TEXTNS,'sequence-ref'), **args) + +def SheetName(**args): + return Element(qname = (TEXTNS,'sheet-name'), **args) + +def SortKey(**args): + return Element(qname = (TEXTNS,'sort-key'), **args) + +def Span(**args): + return Element(qname = (TEXTNS,'span'), **args) + +def Subject(**args): + return Element(qname = (TEXTNS,'subject'), **args) + +def Tab(**args): + return Element(qname = (TEXTNS,'tab'), **args) + +def TableCount(**args): + return Element(qname = (TEXTNS,'table-count'), **args) + +def TableFormula(**args): + return Element(qname = (TEXTNS,'table-formula'), **args) + +def TableIndex(**args): + return Element(qname = (TEXTNS,'table-index'), **args) + +def TableIndexEntryTemplate(**args): + return Element(qname = (TEXTNS,'table-index-entry-template'), **args) + +def TableIndexSource(**args): + return Element(qname = (TEXTNS,'table-index-source'), **args) + +def TableOfContent(**args): + return Element(qname = (TEXTNS,'table-of-content'), **args) + +def TableOfContentEntryTemplate(**args): + return Element(qname = (TEXTNS,'table-of-content-entry-template'), **args) + +def TableOfContentSource(**args): + return Element(qname = (TEXTNS,'table-of-content-source'), **args) + +def TemplateName(**args): + return Element(qname = (TEXTNS,'template-name'), **args) + +def TextInput(**args): + return Element(qname = (TEXTNS,'text-input'), **args) + +def Time(**args): + return Element(qname = (TEXTNS,'time'), **args) + +def Title(**args): + return Element(qname = (TEXTNS,'title'), **args) + +def TocMark(**args): + return Element(qname = (TEXTNS,'toc-mark'), **args) + +def TocMarkEnd(**args): + return Element(qname = (TEXTNS,'toc-mark-end'), **args) + +def TocMarkStart(**args): + return Element(qname = (TEXTNS,'toc-mark-start'), **args) + +def TrackedChanges(**args): + return Element(qname = (TEXTNS,'tracked-changes'), **args) + +def UserDefined(**args): + return Element(qname = (TEXTNS,'user-defined'), **args) + +def UserFieldDecl(**args): + return Element(qname = (TEXTNS,'user-field-decl'), **args) + +def UserFieldDecls(**args): + return Element(qname = (TEXTNS,'user-field-decls'), **args) + +def UserFieldGet(**args): + return Element(qname = (TEXTNS,'user-field-get'), **args) + +def UserFieldInput(**args): + return Element(qname = (TEXTNS,'user-field-input'), **args) + +def UserIndex(**args): + return Element(qname = (TEXTNS,'user-index'), **args) + +def UserIndexEntryTemplate(**args): + return Element(qname = (TEXTNS,'user-index-entry-template'), **args) + +def UserIndexMark(**args): + return Element(qname = (TEXTNS,'user-index-mark'), **args) + +def UserIndexMarkEnd(**args): + return Element(qname = (TEXTNS,'user-index-mark-end'), **args) + +def UserIndexMarkStart(**args): + return Element(qname = (TEXTNS,'user-index-mark-start'), **args) + +def UserIndexSource(**args): + return Element(qname = (TEXTNS,'user-index-source'), **args) + +def VariableDecl(**args): + return Element(qname = (TEXTNS,'variable-decl'), **args) + +def VariableDecls(**args): + return Element(qname = (TEXTNS,'variable-decls'), **args) + +def VariableGet(**args): + return Element(qname = (TEXTNS,'variable-get'), **args) + +def VariableInput(**args): + return Element(qname = (TEXTNS,'variable-input'), **args) + +def VariableSet(**args): + return Element(qname = (TEXTNS,'variable-set'), **args) + +def WordCount(**args): + return Element(qname = (TEXTNS,'word-count'), **args) + diff --git a/src/odf/thumbnail.py b/src/odf/thumbnail.py new file mode 100644 index 0000000000..d6388ccb70 --- /dev/null +++ b/src/odf/thumbnail.py @@ -0,0 +1,427 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# This contains a 128x128 px thumbnail in PNG format +# Taken from http://www.zwahlendesign.ch/en/node/20 +# openoffice_icons/openoffice_icons_linux/openoffice11.png +# License: Freeware +import base64 + +iconstr = """\ +iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAABGdBTUEAANbY1E9YMgAAABl0RVh0 +U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAFoHSURBVHjaYvz//z8DJQAggFhu3LiBU1JI +SOiPmJgYM7IYUD0jMh8ggFhAhKamJuOHDx/+8fPz4zQsMTGRYf78+RjiAAHEBCJOnTr1HZvmN2/e +MDAyQiycOXMmw5MnTxhmzZoViqwGIIAYrl+/DqKM/6OBNWvWgOmvX7/+37Rp0/8jR478//fv3/+f +P3/+h+phPHHixH+AAIK75D8WMGnSpP8vXrz4//v37/9///6Fi4MMALruf3Bw8H+AAAJp5rQrOoeh +edmyZWAbgd77f/bsWTAbBoB6JOpbmkF0OkAAgcLgO8gUYCCCnSIlJQWmw8LCGA4cOAAOAyMjI3hY +gMDvP7+f3791+weQuQAggGBi7FPmrvnf3NwMtgnkt/Xr1//fuXMn2EaQ5TB89+nX/wUlJSDbPUFe +AQgguKleiY2/QIpBTv727TuKJhB+//nf/xtP/4ANrK6tBRnAATIAIICQEwUjUCHIoyjOBYGbz/8y +8HMwMXCzfmcoLC1kMDH3YNDU1mGQ4PvLCBBALEjq/t958Zfh0dt/DL/+MDD8BdkBNIeXnYFBhIeR +4efffwybNqxgEOEXZLjw25Xh2QMWhmi9BwwAAYRsAMO5268ZZMREGGSEGBmYgcEL1MMAcgwo3D9/ ++sIwf84cBhHLGoYAVVYGxi/3wDYABBCKU6dPn37s1vM//3/+/v//20+gn5/9+b/7yq//iw++/6+o +qAhy0zUg1gH5HYYBAgg99Srsvvzz//6Tt//beSf+V/doBGkqheaFL0CKF1kzCAMEECOWfAMSY3Yq +PvF7X68FKCcCPcLAA8QqQHwB3VaAAGKktDwACCCc5QETE5ODjIzMfi4uLoRtjIwiQBe8RVYHEEDg +WODh4dkBTMLuQE1YDdPR0WG4cuUKw6tXr968ffsWxdsAAQTWAbQJq+aenh5wogJpBpUNzMzMGGoA +AggckshZFRmA8sXz58/BeQKY2WA5kRmkp7Oz8z8vL+8WgAACG3Lv3j0Mze/fvwcpBuaLb/9//foF +FweG2U9dXV2RixcvguTNAAKIAVQWaPt2oGgGlT4gzSBDNm/e/P/jx48o8n/+/PlraWkJil5OgAAC +OUDEKvsgWOLdu3f/k5KSwOxPnz79nzt3LrgIQwY/fvz4X1FbDbIgAOQVgAACxcIbFnZesFcEBQXB +AbdhwwYGNjY2BmdnZzANSypffvxn4OFgY/j5+TvI9i0gMYAAgkUJI7Dc+/flyxeGly9fMaipqWEE +9m1gTv329RvDjAmVDE52dgx6enpgvQABBIu7//fvPwCmB14Mze+//geXBwKcTAwn9q9kEOIXYNC2 +8IfLAwQQcqIIOHPv9/o3X/4z/PkLzABAR7KyQMoCPi5Ghm9fvjJM7i5lUDbwYXjI4sIwK41LHBgG +rwACCLk82Pvq038GaQEmBi52iAEwK/4BDbx7cTeDEB8/w42/TgwhRt8ZzNeeeAHyAUAAoSTL15/+ +/f/++z+DrBATw/P3/xgeAkunt5//MSzYcpOhJYyNQUNDowGorA9o82eYHoAAQjFgw6kv/yV4/zLc +v3WRoaRxBoOEtj/D2cXhPECNAcAExAbUiFE5AgQQenkAis/PrkWH/u/us3MGsvdBxYOAeD3QAIy8 +DxBAjNiKJXIAqIZ//PjxYT4+PmtgHmEAJjiGhw8fMhLSBxBALIQUcHBw1AINbAIZCkqUuABywQZM +kwzAnMBw//79TcCy2A+f+QABBA4BoOuZHj169FdWVpYs3wPzKoOAgACKI0BsYCnDwMrKyg204xsu +vQABxAQtkv6FhISUEmuho6Mjw9OnT+F8UNsIWHQxAMsChtOnT4PaSwzAVglYDBgNX9H129raci8C +AhAbIICQkTCoACEWgAoVDw8PcKl17Nix/ydPnvx//vz5/9jMAKqRh9Vi9fX1YLHe3l6QuD1AAMEs +ZwUVi6s37CTK8t27d4MtBrW7QPj169f/79y58x+YCDFKP1jJCIruurq6VyC+t4/Pf2DUgAozSYAA +Atvu4Wm5D+QA47hVoLIWwwBQsVpaWgq2FIRVVVX/gxp427dv/79kyZL/Fy5cAIcIPrBh/QZwtZOS +mvoXmLDngDIOKEQAAgg5CmLsis7+v3XrFlgDyAJIWoIAkM+A8Q5ufYEqidmzZ4Md8PnzZxzVGQSD +wN79+8F0ekb6X2C92AyqRmFRAhBA6PnUVtuv99CVjUXwlAysicEKQZUuKJcAm/7AlM0GrmyBwYi9 +ogWa+hYY6m+AxeDPt9cY9PV0GSoqKxjef/jGMGvGZGmgec9gSgECCFtBofvu3ftLoJQNjFuwI0RF +RRlwNRkQbQ4Ghmfv/jF8BlZaoKDjAzYnb1w4wHDx+lWG98A66s27zwwVZUUM8vJyakAH3IbpAwgg +rCXVxo2bnvr5+Ur9+w+pFX78+s/w8w+kvQnyMCsQs7GAeIwM91//A6r5z8DLAQwRFmDVwwnUA1R6 +4uhBhl0H9jG8efacgZldgCE4Pp+BiUuc4fTNLwyVwUJMsGIZIIBwFZUam89+u84GrND+QZMeKQ04 +acYbDGs3bWR4B/T5kbtcDLouWQycvKLgqp0FGJBGghdu2mgLaoDUAgQQrqL4BjOw/augogGuXNnZ +GBn4OUG+Y2RgY4W2l7//Bwb3P2BpB2oGMjKwMDMy3ARW+5nRbgwB7hYMTk5ODIVdWxmiQp0Yvj5b +9qy1uHIn0NyroH4dyHxYDgAIIHyVhdvzd392vvj4nwGYdhi+AKOBGdpY//vvDwPr348MX94+BVed +fTPXMry4tm02qMbLzs7eBmynrwOWgsuA/G1Ai77jCy2AAMLnAM75S1a/SIwJ3QTqpoAEzFO3N7Nx +CTEwMrMycN8qvLB9y8FAoPADmFna2tp/rl69mglyCKh9QExNCxBAjCTWOxKg+h6Iv2KRAzXDxYD4 +ORD/ROoG4wUAAURx/4BSABBAeMcbSAHA4jUF2M2YDWo3sLOzM0ybNi0SmBBXENIHEEAkt4hALR9g +FTsX2PJJBFrIwMKCPSMB2xcMwI4BwSgGCCC8LSJgBSMtLi5+AGiRCsgyUPFLTJRt3bqVwdXVFRQS +oK7MX3xqAQII7gCgTyKBrZplIIuAwUlyFADbAwwWFhZgB3p7e8OEZYD4IT59AAEEGzKyBuVb9CEC +YsHy5csZysvLUUIH1Bq6du3aLdBACD69AAEEC4GXwHYAuHYjFqxevZph3bp1DCtWrACH2Pfv38EO +AHWQgFU0OLqEhYXZQM00fAAggGBV3DPYeA8hAEq0SkpKDKGhoWCfgywFWQ7shTLcvXuXAdjzBLeI +QVEpIiICCl1hdDMWLFiwCtirBdsNEEDwEQdgcBFsih08eBCFD2qOgTqloEYMaIwJmPjATTPkLvG2 +bds2IY9sAHt/6rDhNFAAAAQQ3FWtra1biW2Qgjrvly5dAteTwP422HJQo/TBgwcYTTpgg+Y/zHIX +FxdWYGj9P3fu3H9g6LwHNYQBAgil8kEel8NneXp6OthyUF8e1H8HNddAoYGtPQlSD+3LM2ZmZoLF +Nm7c+B86XMcLEEBgmw10JazMUrYSbFiC23VQy0EhABreACa6/8BCBxz0oEEFbJ4ANmiDgXoEQOyG +1tb/VlZWIDNAvWxGgABiSSqseXiHMUju359fDEADGCQkJHAmwJUrV4LbiKDEBeyxgjodDLdv3wY3 +19TV1Rm4ubkZsGXlnJycNdpa2vfAQwXAtAbsP2wEMu+AWkUAAQQSkwU1yUH4ypUrGK4HKQImJHiT +HIRBiezy5cvgJjko4b18+fI/vugDhdK/P//+VTfU/09ISACNliaCogWULgACCJQVHp+aYtQEToiz +9qK4fP/+/aBsBC5WQdkNVLiAshtoCBqU3Tg5ORmMjY3BjVZ8hdiZM2eBbQhGxhdPnv4DOrofZDSs +oQIQQOC8+OMXQw+IvvaSB16axcTEMJiYmID5oKY3KG/fvHmTAZjwwMUuyCGgQTRcloOMAeFPX34A ++4I2DKWVlUA9P38DE+oRoDS8YwkQQLCS8POhPiNfi/Rdm0H9ehUVFXjnE2QRsMvFAExkDF+/fgWX +lqAmu4KCArifAIp/XPXTm8//GW5dPs9gbW3JwAxUtGL5ik7ooOVvmBqAAEKuDXfwcLIwvH37Fm45 +MHuBfQ2MY3DilJSUZIDUikxgi5EHsVC668DAffcF2Ef4/BVseU5hAYMwjyBo3ABUN7xEVgsQQMi9 +jT97JjgZvHkDGc8E9e1BdfqPHz8Z9PUNGLS1QcEtBox3LnDZj2uw4hWwEfvyw1+G38B+BOsviEcE +efkYXgNzGLC/0Qn0/R9k9QABhN7duTRn/pyPIF/9/PkLWJ9zAC3WBscz1i4YUsPy0zfIAPuHb//A +vSRulh8MZ8+dY4iMjWX49/cfg6OjHYORiYU0ul6AAMKWdAP+/v23HpT4YAmQEHj05h/Dj9//wRYL +8zCBHXTs4DaG81cuM7x98YLh229mhqjEPAZpaRkGNSkWPuRhMoAAwtbhOwmKe2ZmYDwDLf8G7A98 ++g7qG/wHxi2w5gPy//6HWPYOmMhuPvsL7raJAC2WFmQGdlCAXTfGbwzPgenm0YMHQHNYGGxsHRg+ +M4kz3H71jyGlbGoOsmUAAYStSfbm3M3XDAIiUkAL/zF8+8nI8PM3pMMJshSMQcPGTJA+IiewCcEJ +7Dm9AAYzGzNktuHZrdMMt+7eYeAA9qKffGBmEPinx3DkNNDRTH8Yfoh4tAHzVjvMMoAAwhYCv6/f +f/Xv6XtgKgam5j/AugTUMQZZyMSImKwAWfQdmJnefQM1Jv6D50zuAH14/fFnBhU1VYY3r18y8PHx +M3zms2F4/EUEaDmk06ogKw4q3OAeBwggrI3SnprEqgnLz3aAesCgXi8fEIPLGuiEDIyJngVBFZ+l +jgLDbWCZIcgrwLDj4l8GbSdDBi52JgZ3/f8M74FZ/O2rZ7C2IrhHBRBAWB1w89rlAwrC0PAGdXlY +GRmE+BjBQQ0S+v7zP8MvoO+/AtPDDyAN6jPyczEyHLryHjyC9ub1awZhUQkGHVZRBnOJ2wzt5Zbb +Jj55AuqYngXlNOSSECCAcBXgou8/fnn16RcneGxAQpAJHBKgIASNmoMGgD8AE+QXYBR9A6aPP7// +MGw69prh8e1zDOZCFxiAjRSGkJCQbaD5JKilr9HzPwwABBAuBzBdu3n/LwuvLDCOgTng639wnP+D +TFcC8Q+Gv19fMnx5/5yhu386w9kDK0CWzAE269k3bdo0wc7ODlTkggai7mIbH0YGAAGEq2Py7/jl +J98klKW5+Dj+MvAxfWJ4+/opw707VxnaJq1g4BRUYOCT1GWQF3z9G2i5JdSXjOvXr/8HtXwZMZaD +AEAA4esIRLu7e+bu3Ln9JJB9xSh2+SwOPikG2AQHsPIKh3bDwRULsGiWB9aeB48dOxYH5B4FZRRi +un0AAYTPAWxQ+Z9Qvg2w0XIYaDGo6gb58g2aen0gVgXiXaCSmdjuOUAAkdIVAqlVBjWlcMhLgio0 +qMP+E+sAgACi2nwBLQGoRw7se7gCO7uJwHZnBLBNyobcpqAEAAQQy0B6DNjkUAR6KAnYvIgFpWFQ +EwM0tgEackBu5SH3eUHNlNOnT98GBgpovPMXpW4ACCAWWsQWsPUYB/RIPNBjjjBPgVqShAZ7iQGg +1omysrK8lpaWJpB7kVLzAAKI6CwA9IAlECcBPRMDxBwgj4EwrgEiagDQnHdRURHD4sWLGbq7uxlK +Skrgcvfv3weNEaA0rcgBAAEEDwBQzC1cuNDO39//AB8fHwO5QzUUZgmG3t5ehoqKCnCyB3UPQHMT +2ABoQGTt2rU9sbGxZcTUN7gAQACxII26/AcGwndQgIACgB4A5MEHwDbrt2/fGC5cuMCQl5cHbkb8 +g89aI8oAkBhoCAuEQWxQdrK1tQUlCVA38xm5bgAIIPRMeX/Xrl0HQQ6iNgD1Ljdu3Ahf2hQVFQVO +xvr6+iCPMOTm5oI9eunSJUgHDehR0Fjb8+fPwaMP165dA9MgPkgclFrExMRAXeRjwIhjJdddAAGE +UgYADQL1f1yBsbJdTk6OKtkAlH+zs7PBMY0rOYNiFIRBngIFFMiDoNQBKgNAM+CgIRfQcAxIP6hX +DCp7YAUqaDjHxsbGAJgdLuIrmC0tLa+tXLlSA2Tew4cP/8bFxXE9efLkH0AAYRSCQMWKBw8ePG9h +YcGPb5qeGIBtZRhsNh00/gByfG1tLcPSpUvBMd7f389gaGgIlgOpA2VF0HAAqFMMWo6Eq3967949 +UM2AtUD08vLiAeK7QHvEQOtjgCmcAeh50Ey/FjDQHwIEEDbzuCQlJVNB403UBKCRPNDYZEZGxn9g +coePc7W0tPwHDc6C1iEBYwS8aAlkN2jgFbT+CNuQIzoAqQOmtG5YioZGKouTk9NP0FgodNnR/zlz +5vzfsWPHf2Dq6QOldCAWAQggbM1NXv9Q/9OggTpcq6tIBaAx1Pz8/P8bNmyAexxkPmjFJmzBJciB +oOFR0BQ4aMUWSA/IYyB5YsZtQdPpoKk0qOfZHBwcnoNGob/+/P5/2owZ/1tbW/8fPXoUZn8CA2Rp +HStAADFCPS0UXTbt3uM/FuDi/8+PTwzavNcYeqqiKa4ROjo6wENtoDF9cHe7p4ehsLAQnMRBox+g +/A5aeAIa+wMlfVAyB+VzUHIF2Q0agCSmrQHKVsCa5AGwR6QBbKeI37x585S8vLz49bt3GKrLKxiE +geYBszaoIAWtGQCtKboIDKz3AAEEMhlUglrCPA9OOxy8DCfvsYCn7EFTb8QWhiALlixZAsqP4NId +BCorK1GW9IAKO1DeB40zg0p0EBvkeJA9oPwuLi4OXoUDaj0SMyaF3EJUVFRUAJZhFgcOHlwtBiw4 +rty6yVBXVc1gaW7+e+bMmX/v3r3bC+0qgpZ1fgTpAwggRqT2gI1D0en9/xgglv78/JIhy/kPQ5i/ +C96JM1DVBmrmIk2OMVhbWzP4+vqCqylQTIPqeGDeZ5CWlmZ49uwZeGAdFLigwACV7KAaB7QaGDTo +CjKLnNoHZA9oDJWNg51BSECQ4cLVqwz1wALWztr61+zZs/8CU0QtdLIe5Pn3oNVKIH0AAcSI1iYw +DClZfOLVP22Wf39/Mby7e4hh98xo+FJlGAAtS9q5cydDQkICQ1JSEsPcuXMxqjVQqQ6q0kDJHJS0 +QUkd5GlQAIDm0UClOmh0GTTKDKriQDFOnsch9j14cB8YgIJAs4QYTl04z9Bc38BgbWnxa+HCRb9u +3LhRCvU8qCv9GbnlCBBAjFgKQZXo9MwDj7lTpb69vccwr1gNPEkAyoegUAbFKmhcHjR5gJ4HQR4F +5WVQsgZNEILYoCYrKOmD5EGBAqveQLEOzKPgFIArqROaFgbJv//yl+E2MKmrK0sByw0BhqOnTjK0 +tbQymJub/dm6ecvXUydPlgGVnoZ6/gt6sxkggHAFuZStrfb0f/oz/ER/n2GY1x4PLpSAfQWG+Ph4 +lGQHimVQIQZqtIBiGDSHAAKgGAU1YEAxDcpCIE+CYhjUgIHI8eCt23EtDQItGP/4DTRI9h/o+X8M +j+9fY7AxVgWaxcmw/8gRhq72dgYfbx+GbVu3MWzbtiULmudB81NfsfUZAAIIX5oDNdviDCLm969s +tGJQVVVFSaIgj4Nmd0GFGSjGQYEBKshAMcrLCym9YV1gSlqUIK0/gb3+Lz//M4DWp3798R+ezR7e +vshgZ64N9vzOffsYJgA7UmGh4cDGzg4GNQ19hlUrFmfcuH51KS7PgwBAABFyGTdotqp76vIZWQl+ +DLDF4aA5E5CnQRjkEJDHQSU3SJ4a3WOQp0EDvp+BMf3l5z8wm4kRkez//vvL8PzueQZBXlaGA0eP +APM+L8OqlasZEmPjGLZs3sygq2/IYGRmy8DPx8NgYaIjBKrucNkFEEDERA1oPX7Z06fPakEzVKCY +BuVpUOEGHY2k2mDHT6BHQTMhn779g+yLgI3GM0JWwoGG6n//Bub5GxeAofCDYdf+feAIuHDmLIOn +pwfDWSCtpaPHYGRqzSAjr8bwl4GN4cal4/uC/ZxdYaU+OgAIIGKiC7SbYQ0wf9eCCkBQnoUNhmAL +TZiDiVmKBFL3DZi8P4Cm84Aeh818gD3MCfEwaECcA9hS4WJnZPj2/Q/DjZvnGVgY/zFs2buH4dfv +XwwXz55jcHJwZLh46QaDpJIeg4qOLYOEHNDzzFwMX4Fm/+RRd4LORTzC5gaAACI2c/L7+fnX9U+Z +W8TOLcjw4w+ou/of4mFGREiCVheCkuq//4jQ+AddrffnH2Q66ecfyLJDYIUAXob4H+pvUALi4WAE +eg6Y74CeZwZng/8MXGyM4MV77z7/YTh/9igDO8tfhv2HD4Gr1XvA7rGRgSHDk2cvGIRkdBgUtKwY +FJWUGV594WC49OgfUA/QTqb/DNy/b3+fmGcgCEwFP9E9BhBApJROVnM3Xz0qLq0CXiXIiJQn/xNZ +bRGq0hiQZp1AAQlis4Irib8MX5+cAmaDfwyHjh4GN3hePX/BoKWpxXDl9nMGRkEDBhZxCwZeEQUG +VnYuFHMFuBgZXr37yHB6frD1mmVzjqHbCxBApJRYd989vnRDSFRagxVY2KE7GBTTyEkfFOuw/QxM +0Lk1ZmhJxsQEmnAEBiJUzz/QfA+QAZoLBPFBMQ5SCp4P+veHYd/ayQyeThYMf5mYwY2mA3v3MTjY +2TOsP/yYQVDWhEFc0pyBT0SRgZmVA6wXZIacMCODtjwzMACAfY5ffAy2SvOOamqqg1IBysIkgAAi +JQWAAstj54n7m+VlpRkYgWkWFDl//6PGPCz1w1begqZsQetLQROczEAT/v+DrEVlBq3EBQYEKIBA ++kFiIDlQVmAH5oPfQPY3YPE/d/kOhsnNmQx1dXVg80FtClC12j5nP4OIgjmDsLwZg7aaNIOGFNCQ +318Yvnz9zPDtyycG1l8vv+/duvzaxg3rQas+QbUAaHpwKzAAUMoCgAAiJQWAZl1u/Pr8+g8zgySL +IBczMK8ygh0LCvHfwJAANVJAc9pfvjFA5rGheZyXG6IOtCKNm50RkufBSZwRHDi//oECCVHPP3r3 +n+HOiz8MB84+Z1hbG85QX18H7iGCWqCgwY/mrml/OX99eHp40XzwXOcGYOucAbJi9DFopQJ0dgg0 +PQVqlf3CN2gKEECkVtrPw/0ds05cuDdLUkiUgYMFMl0MSqqgCdsvPyHzp8CaiuEbkA2a0P/5F5Sk +/4HV/IUmedA8J0iM4T+wifz7BzDGvjB8+/aJ4dzNTwzs/94zPDm/+sW61YtBnvsI7G+EgjwOnnzT +198DigRo6w7UvH1M6eQIQACRGgBfv337eu78rZcMz77xAz3EBE7qoOQNbqBAS3w2pn/A0vwPA/P/ +XwzMwGT5++snhi/AfsGfH58ZDhw6yrB+x3Fgl5uPgZVTgIGVS5iB+/3Gu5cu3JwH9RhoNQson7J2 +dnbeBdXzISEhi4HtjtfQadhz0Jj+RslwOAwABBA5zbYH146t26wYmuoL9D445j59+szw68fn/6eO +7Hy6ceMG4R9cepwsQM+BVlqz80owsHELAz0rCB5nYGb1YNDx8WDY32cFmmXdDp2yfwdJF4iZ2ebm +5sfAzpNQbW1tFTAQQJ6/AO3QgJL2P2rNaQIEECOZekBp0hwaU8+hee49NM8JGBrId/E6rY9Cnbo9 +9mtlX04xkAlarXWbAfsKcGjjkq0F2NfwgY75g8y/Ah37/4U0j0GVAAAIIFpN/4A6UmG+gS6pm9fv +6YT2xZ/CJvMJuIcX2nKTgMb2I2gKQVljQa0AAAgg+s9/EZctWaBu+w1uBWHZQkKtAAAIoAHfPzDQ +ACCAqLZ/gZYA2PsUAbYDkoGNoOi/f/+elJWVTaNGDQACAAHEMtg8C+xtGgMLQdCiiRggzQcaPUKe +hn/06JEukCqE9lIpBgABNGABAJqvu3v3biDQcwlAT/rCutggjG+YDDTSxABZ8U6VAAAIILoEwMeP +H/nExMSSgZ6LA8asAciToAFUEE3qcBmoSbx48eIcYACWUSMbAAQQ1QOAiYlJFxijoJUksUAsDPIk +aGaIWitJQJ0hU1PTPCAT1Dv6Tql5AAHEQkkSvnPnjjfQk6AkHAwaFoPlV1JGeokFt27dAk+ogNbw +8/Lygoaj+KkRAAABxEJkEmYXFRVNAXouHpgHTSlJwqQA0CYl0KoRkB2ghROwgxdAg7DA7rEDkLmC +UjsAAgjbIil1oCfBSRjoQUlYrJKyu4oSAJo8aWxsZGhpaQHzQVsI0GemQJMs58+ffwjMCqqUrhcE +CCAWpCTNAUxi30GW0XLlFz6wY8cOhm3btjFMnjwZfMzSvHnzcFWVoBkqeSATNKH7lhI7AQII2aeg +c2zuiYuLKw1EAGzZsoVh1apV4CU1oO0xoAlW7GOHkAVToDkIYKTJUhoAAAGE7NPfu3fvPmphYaEE +Svb0SOqgPX+g6TRQeQKaaAWtCwJNnoLmH5ABbP0QSA+IBgFQluzs7GwGBkIgrsXoxACAAEJeJwjy +tT/QASvRHUBNcOLECXCBBtqLtGfPHlBehssdP34cvBcVOa8jzzCDAgB2lgGoOgTNUqurq/MD/fCJ +XPcABBByCgD1tV+AJjexLW6iFID6HKBtp9XV1eApcdBiSBCGrRwDeRQ22QKKcdDsE8gtoKl0EA3b +5gqbbAWxoatXBKHdZrIAQAAxIXUvQa2qt6CQhiUzagHQMlfQFDtkp9l/8PrA9PR0lGVzMM+D7AZN +qYNmm0H79EAYNgcJagaDWoKgQACpBwUAtFVIMLaAhWrUokWLDgL9aY4sDhBA6BN6H65evXoLFPrU +AqB1AKB1AiCPg2IcW6EGS+ogj4PUgiY+QB4H0aDkD/KwsLAwGIM8DZtuBwUItFWId+93dHS0eEBA +wJKmpiY7QUHBE8AI2QvN9kwAAYRe3H8BFoR73N3d1aCdDoqAoqIieAceNgAr1JDzOCibwM4mAk19 +gWIZ5GnQuiHQ8hlQ4Yw8CQvKpoRahaBNUubm5mdiY2MZQakIlJ02bNjgAKxiQWXeL4AAQk8B3+fO +nbsXtsiBEgDyFCipowOQI0ByoJjetGkTfAuqm5sbOGa/gIfIv4E9C5qMBRXIoKwCksM2Aw0KsNLS +UmtczfWqqqrslJQUGVD75syZM+B5BWCqew1tQzABBBC2ITJr0M5wYtbmkQpAawFBB/2ATjg0NDSE +rxlcunTpf2ANAN4MDtoUfvr0afDiSdCCSdAebXxuAZkJVP8AVDOiHebH6Ojo+AHoafiud9CJksAs +AFooCVrmAtrfww4QQOhZAFwQghYoApMoIzUbRKDkfvToUXBDB9S8BVV/oGwG2g8Mil3kTRWwKXhY +aY+vRsLWKgTFPDD7cTo5OfGDVp/DaiGQWba2tn+AKQ+U/ME9NoAAwubDj2fPnr2sqqqqR60AAOX3 +9vZ2sOdA+5FB63VBHZu9e/eCCzjYNhnYchpYNUxsVQzKBlpaWjJIrUIWYEx/Bq1MBwUkyP5jx46B +p9aAnmeBDuGDlsT/BQggJiztAuH1R1/pggoiaoH6+npwPgYGLNjzoCoRdAoYKO+DCjdQSgB5HpRK +QDUBqAyANXyIGbQFLcbq6ekBtQqZQbEvIiIiYGVlxQQKmMvA7NDX1wcuT0CbMYABAjpXCzR/CFpY +/RcggFiQ8j5/aknt6Rt//FTu3z8CdgRoZRilDSLQSnBQSQ7y2Pr168GrQUHJH5a6QJ4EeRbmaVBs +geRAKQPkMWJSISiWgS1CXwbI0To/gO0GXmDT+j+wgGW8AWxunwQWfpcvXwY3xIDgALTh9BPU9gEI +IJDp7EH+phFvlGcuuAk6ahQ0t8clzECNmgA2fg/q2Hh5eYH5oPodFKiw2AbVBqDVZqDSH9bYAaUK +UN6GLa0jNhtAW4VvJ06cuFNbWxs01cYMOnOEA5j3QRsugI2obUB73kHHE8GNHYAAAmUBaZDnUfIB +Bx94Cz65LULQ5ghQzIMKPNCZlTDPg8RBHgJVg6DWHSgwQNUSqK0AW2oHinVQYweUAkhZfAVqIQJb +ernAVMsbHh7OCyxAmUELpa8A+x3A5P8PtBwf6HnQ/CJoiu0jdMKFASCAQKb/lf4w4S5KALDzMGw/ +fBW+EozYer+hoQG8Ehy0aBpU74I6PKBDtkAAtBECtDQW1swFDW+B2gmgDg2oMQTyAKjBA8qroBQA +a+2RMlYITPJ5EydOOAEMBNAJUwwrli1nEOTn//fu3bs/wOy1kgFywM8TBshyWfBkLEAAgQLg+fJ5 +i3JR2sesHAz7zr5kILYgBK0g3b59O7hkB7YkwV1bkMeBTU+4GlAfH2QeqMsLqglAGLScFhTDoGUv +MjIy4PIBFPsUDLWxOTu78gMDjvEysNq7dOECg6aGxl9gO+EfMOBBjQNQRIMaQfCYBQggFmgv8Pyz +DS6zpAL2pIEDgJmd4c03SKsMVHrjcgwoX4GWvIPorq4usBjIE5mZmaATVcHJGORh0EgPKDZh/X1Q +OwBkNii/g2Ic5HlQjQDikzugCuq/fPzwkUFdQ1UAHPvAvC8iJPQPWPiBlsnPYoCsOwC1yz8hrxkE +CCBYEfv6zr13C1UY36d9+w8s+ZmYGVi5BOEnJWELAFCMgo75ADYzwckX1MgBVj1YOzqgAAGtJwZ1 +bkBJHtTFBeVvUMyDltCDaEo8D1sqr6yizMDMxMpw7vIlcOzb29r8mT17zl9g9gR5/h567IMAQADB +ShhQgXBtR69zFkyClYOf4cWrd+DSGh2A8jiwcwH2PGgrG8hDyJ6HrRwHeRoU6yBPg2IelFpAYqAA +BVWxoHY+yPOkLppG9Tyk/Ll29TqDsAjkAKmVK1YyiAMLvqtXroEKvwnQvA9aZ4CxZhgggJCLWFDJ +eEjm/x5w/cfMxg0sCG+ACyhkADpHy8HBgcHPzw8c8qBJD2SPg1INqFoDeRZ24hBoTB9U2oOGv0Dm +gTwMSvIgz4NKfWI9Dzsi5z/SyrT///8xXL/1kMHU3BQY+8wMJ4CNravAOl9ZSfnP8RPHvgMjELSc +5inUfxixCRBALGj9gPvL+ssS7YrOrQKtudt//jVDMbCBAkriIABqURUXF4M9BurnIydB2AgOyPOg +wg1UrYH4oNhB3vEJ8jyoXAF5HlR342vo4GsEgpfZAhPzu4/ArvOHVwyCupA5g1WrVgIbRSpANz74 +//DhoxkMkPVEoKSPdU0RQACh2w5qH58SfFh56p1cq9kPBl5wCw12YhrI8+hNU1CsgzwJ2zMASvKg +LAEbVIHtG4DV56DqChT7sH1BsPKFlGUKoMWQn779B680u3HrDoO5oQHYnIPA9v6N6zcYXBwdGRYt +XPgVmA3vI8U+1kYNQABhC/5nG9furLIrat8DWtgEC4CAgACsngfJg2IctG8AFPuwsT1QXQ7yOKhw +Q97pCRvXA22YAJ2LRIrHQWEFOlEEVCyBzlB59/E7gxDXX1grkGHdmjUMOsB+xof3HxiuXr26HFrn +g2L/O66JVIAAwnqUDRBfvrnYsg/UInzw+BU4NkE9N3TPg5I4bPcXyPOwOh20FQa0cww0IgTZECUN +LPCkwBh0JhPoiBtS6nrwThGgq95+hhwm9OYr6Iyfvwyvnt6GT5ftPngAWN7cAtqpwHDrzi2GiKhY +FwbIAspPuGIfBAACCFc78+3L1z9XiLC//rfj6C2MghCUl0GFHSjmQUkeVOKDyglQlQYa8QUdmwTy +KD+/ADimQakAlPRh/X70EyLwl3yQWActp38P9DhoPwFI56+fPxhkRDmA9nKDlW1Yt57B2MgE2MZ4 +wSAkLMVgaGyuDh0m+4FvGh0ggHAFACjEbm6bmph18OI7BuTd5LB9QqB8Dsr3oMAQEBAEexoUw4KC +QuCkT+kmCvDxLX8g55KB8vubL5DVprDU9+zBTQZFYGCDwLbdu8C1jaqyCrBtcoNBQU6KQUddEWYM +3g4NQADhcyGov3xY7P+5j7ByAGL5P/BpX9+//wB6kBnsYVC7H1SwgVIBufv+0D3/Hhjm7z//Y3gH +Su7Qw7pALgDvRfj7k4HpzzuGNevXMazZuJFhy6bNDJampuC+B6htISElx8AvJscwceLkIEJ2AQQQ +E/7Ex3Bvz+bV9aA9Qoj6F3LSGMijoJIc1JSFleiUbpuB7QoDndX0DohBB4jBAgTkcdDaZEHO/wwf +XtwB2ivOcA/Yuzx//hywN/kQmPUUge2N2wzSMrIMmmoKDGqKUgzWdk7VDJDzgHACgAAiNNoA6g2d +BvbZ/wGTHRMs78ImJUB8ap0jAj4DEJTXf/4H7xBjZEDsPwB5nIcTkqq+ASv/r5/fMVy78YiBA1i2 +3Lt7l0FPW5fhDpCWkBRnkJFVYmDlFmf4+IMDWKfzgsb2QX2Dl7jsBQggYqLs/smTJ27Beoaw4/xA ++RxUqFHqefAOMWAZ+/LTf4ZXwFj/CvU8eA8B0OMivEwM3KCTvEBVKPM/hif3L4PPtr4PbIx9/gRs +agNbl5Cjyd8x8AnLMnAKyDL8ZeEHNvmYGPh4eBk8fYK08dkPEEDEBMCn/Pz86aBSHzYZARutwZXk +GdFoXB4HD0EDC7kXH4DJHZjX/0G334D2FIE8DtpDBB7t4WIEn5cGKndAVfI9YJJnBAbC08dPGJSA +SR80qvSHkZNBXFoR2BsVB3qcA1hjABsBn9kZotPK5iGfIIcOAAKImOgD+fwmrCBkgm57+Qvd3QGq +n3/9hZQN4H4T1GNMDBB5kEdBu0ZA2yQgZ7RDxL8CExSogANtkGCEbuIHJSbQ9jiYGlDMgzZn/QTW +/Rxs/xju3boMNucBMPa/f//G8ArYyVIwNWN4+OQlg6qaJugweYb3f/gYPr1hAqaW/wxvvzAzHLsn +CBoyB7XlsZ7hCxBAxAQAKPW9ffv+CwMb31+G33+ZgB7+D94OA9shBk4I/xHbZUD7BpihGynAaqDi +0L0S4MBhYERsjgKZwcsJ2jEG2VnCycYAPikRZAc7KyPDb2DA3n/2DVzt3n94H7xd7svnTwyyMjIM +n4DVMTsnL8NvLjmGrwzAzhUjO8P5+8DAevGPQYyfkeHHf3A/RhRXAAAEELEZ+M2TVx++cQn/5mJi +YQNvZwPV0d9/gUptSEkN2hYHa9b+Q/IYOCCQdoGBNleAT2UESjAz/gemCkbwJguQmSAZkOf/ADWA +jg/8/x+y2eoHMIk9un0B3Oh5/voVw3dganz98jV4y9yFG48ZZJR1GfiE5BhOPeIBFn7/wZuyQJEC +akCxsnMzVE7YMQWYDTyxbZ4ECCBiA+Dz0SOHD//h1XTn5mFBKaFh9SUjUqZnxkHDCjdwfQ4MOFCb +G+Tx/9CtNKAN0UyMsJ0nEFNBSfnPr+8MrAy/GK5cv8vw9dtX8F0+wP4+OEX8ZRFkePhNjuHtMyEG +Lj52BuSeNShSmJhZGR59l3GDDpljrC4FCCBiK+5v3S2VS379/A452hLN88g0uTUBAyx1MEK23cBM +/fkb2Od4fpHByMiYQUpWhuHLx88Mn4D9DkkJKYaDl94xvPkry8DGK8PAzsUL7lyhjx0oSTAzaCmA +F1IIYLMbIICITQGgOvDZD2Do//uHKAj/w/sGiC2zIDbIIyAOEzCJs4L2D4JikhGRD0AeBJcTwFj+ +9x+0fxBC/2eA7CeEtDoh+wh/AmP/9+dnDEdPfAGP+LwGdr6kxCWA3fPPDP/YgP0NUXkGDl4RBmYW +drCHQQWyALD2V5dhYlARhxROHz9yMJRV1oFOjcG4wAgggIgNAJCL3v0COgYUAP8ZIHe2gU5VZQWm +bw5WUOEF3SzJAKEhSZ0RvgEStDHyP9QkRkbYRktGaEqCjQkwQrMSRBzY+mIwt5QDjzBPmTKFYc++ +fcBW3wMGG0trhgVbrjAIyZkw8AjJMDCy8ALtYGJQFmNk0JAB1h5sv4F9lW8Mz55+Ae8h/A10t6GJ +RRKwHFiKvssMIIBIacW85f7/7r2UwB9BLtDmRQZEgYdcXcCqSPDuT1BMQ/cQM0PTOQsrKFVAPAra +LAkrI0ClP6g8ZWOGlAkgvadvfQMPxIDmC0BrB0FrCDrbOhhWrFjJwM4rycAhoMDAySvAYKr8l0GY +8w2wlfiF4cndjwys/78xPL5x7OmCOdMuALvqL6HjgfuxNU0AAoiUAPhyeM/6rRra+jHAJiB0Hz8D +tIUGSQnswBTBww6p70H7i1mQCiRQbQHaHg9K6qCzekF7C0E0qBAE6f3C8B+8hZaXiwl8aPCdFz8Z +7jz4AG5xgqa4QR0t0PgC6Hqlg1d/MEgr8TIYyf1iEBG4B+z1v/uxevuq6+vWrgbt/ngHHQR5Bh0Q +gW2kfMuAtOkKBgACiJRuG3gZ3ZHzj1cqyUuBW2mgqgrkSVAqAHViQB4CbZz8Br0h5e8/SMBwcUCy +BUg9JysjvO0AKi/AbYr/kOYw6BDblx//MTz98B9YwH0BtvNvMTzfUwjOAqBRaNC9evWds4F5/O+X +OzcvX3v58uVd6JDXS6hnn0E9C5v/+0FoDSFAAJGSAsDL6MR5fgA9D7l35jWw7Q5L6qCmKg/QgxIC +TPCNlKBTtsG7SH9B1IPO/PgBPRIYVEWBYh+8dfYvpCT9++83w5X7Xxku3vkMLPheMDy/vpPBztaW +wcDAADys3tPT8/Lq6ROg1SCgbXTHGSC7SGFzfQS3yWIDAAFESgCAC8L7z78x8IkAW1kCLPDqCpS0 +wUNVn0FJ+h+4kQQ+9/gXxHOgghMUUKB2DbhQBLXy/oMkfjH8+Qls4X36zPD+/QeGs7c+Mwj/Pv/r +4vq512/evHFfVFTU0ts4Txw09L5ixYrXJ06cOMgA2T0K2gYP2gz9gdJNEwABRGpX7u339w8f//uj +Ivv8HSPDp++QZP/tNyQ2QdkA3A+AlvL/oS3Bf/+BFSEwdln+/2D49xtYlX7/zPDzG7Aa+/WJYee+ +wwxb95xm4AU2V+7dvAHaGwyawQUdjfddR0fHH3Sjwfnz5790dnZuZoDsMgXtGb4JneKieMcIQACR +GgDfZsyas/KfiEUJOw8rOPkyQmMV3BZghJzYwMr0D9xyY/jzneHXj08MX4F1NqiEfvboHsPaLfsZ +7j5+ywDeWsspyMDHy/b/9c1ds4Gl1mGg+WegJfYPAQEB5cbGRsZp06b9XwEq9iGevgid4PxI6C4Z +YgFAAJE6dgXaNOC9aNeD9YIiUuDSn53lHwMHy18Gpr+/QPuHgc1U6F5iYCwfPX6cYe3WowxMrDzg +uUZWLiFgo0WCgZVbBDz19mZ/4pb7D94vgObnl0jjd+zd3d1P//79K1xVVdX379+/N9CkfxVawv+i +1sZJgAAiNQWAmu+v+FiAeZX1HTAZfwG3yF4Ae2QfXj/4smTBrKe33/Gpg3eFg2KYR4xBTCcQHNMs +QA8zs3ExMLNyMsh8nf96+ezp5VCP30ebsGRUUFAIAhZ8wgsWLHgD9Pwz6MzuTWgJ/4uBigAggMgZ +znnH9Ovjr80r1jyfMqnv3OfPn99CHQaKwe9WNiZ5v1VTtUCHgIM8zMTMBll3AxrYYHr+f2uPPWi9 +LCi5X4OO2aPnYzbQjpXU1NR/Dx48aIZmidvQ+pyqngcBgAAiZ/gWtA7HEUrD5t3eQj0DSiGWDkWn +d8NOpYOB55vc1t6+82YBNCm/wjFcDXKPILD0f/r69esMaODcgKaAj8iBRa0sABBA5G6f54Y65gcW +j4iJi7KXq8ceB19kKP15Nr7kjg5AoQZa3qLHANmBDkpZ16EzPDTZPQ4QQORkgf8M+Hdtvnn5+udy +B6Yz2St70uoIJHdsgcsEbdR8g3r8HaHJDUoAQADRas8baPBBCuqRVyR4ABQhoJlOPqgeWAsPYySH +WikAIIBotTsKFHt3yND3F+rhn1D2b2yepyYACKAhcb/AUAdycnKijx49ej0Y3QYQQCyj0UM6AK3H +vnbtmjILC4sRKyurAZDWB2I9ZmZmGdicEQyDJtJfvXr1DKgHdO7MF2pdjEEtABBAoyUAUqSeO3dO +gIeHxwgYmYbAyDMAYm1QBKNHKjImtBAAlABAa+MuXLiw2MfHB3SI0FtcRzsOBAAIIJaRELG3bt0C +5VBDJiYmUMTqAyNVF0gLIkck7Exv0GwvNc4GhfedWVnBK7iA7ohNTExcNH/+/OMMuE+QojsACKAh +WQKAIvXSpUuyXFxcoAgF51ZQEQzEirANV6A1C8gRTOnRvpQA0AJR0EIy0GHv9vb2oEtAX1Cy2Zua +ACCABlUCePHiBbesrKwhMKJAOdYYGHF60IhlJbcIHiwAtJwSVBVs2rSpMD8/fwF0RG/AT/ACCCAW +euRWYMrXBOZAI2h9qg+NVDH03ApaV4pv0c1gBaDVkqB7aEFHzYNORgAtJAJdLADaJQUazIdt8QZV +BQ4ODqA1a6C77b8TGBWhCwAIILJKAFCkXr16VYyNjQ25waQHjGB1WKSiF8MDWQRTC4Dm60ERDTrk +ZNasWeBiHQRAuz7KysoYsrKy8N5FAlpODyoFzp8/v9TPzw90ENqbgS4FAAKIBUcEMwEdZgX0TBe0 +e8MNikBYhMIaTEOpCCYXgJbdgnbAga4HAR3tA9rjCA0j8C455CtFCAHYwlJtbe1oYINwwWBoEAIE +ELYLpkDlL9CdfPLHjh07JSEhwYZvx9xwBKAtD6CDbUA5HHTQzbRp08DioP0dkyZNYkhOTh42DUKA +AMJW2YKPcv/06RPfoUOHzoACA3mR/HAFoJ0HoLr88OHD4MifPXs2+EIgUOSD1qWAdiGAGnLERD7s +jCvk01FgJ6SAxEElgbS0tFlvb28YKLMRc/YNrQBAAGFUAdDbFkFj2R/WrFmzzc7OzgpU5JO6g3mw +AVAEgLamwzYtgiIHtp0FtMIatOcXtBES+bQX0EKkAwcOoOwLxBXZyPcEwjCIj5xxYGMMoHAEhSew +BADdvQVa7AAK7x8DES4AAYS1EQhdUg46zVl33bp1U42MjBRBy9PIvQFqIABoExeo/gZFOqjeBh2b +AzqlDrSkFgZg13rBLnSD7YkE7X4D7XoH3XyJL8Jhm0BBy/ZBCQzGhsnDIh3WIIadxQhiw+5ZAzYq +lwUEBBQMVIMQIICwNgJBdRIwEYDmPF/vBQIgO4Uep2ZSCkCbVUFHkoAiG3RoBbCnAt6Z6+PjwxAT +EwNeYAra0kRO6x+2+R1WpIPCA4ZBRTss4kEAFOGgiIZFOPJBnKDIh+02Apmpo6MTBWwQzqd2g3Dt +2rWcoqKi7MCq5hOwe41z6BkggHB2A6EnCkoDsdHRo0cXKCgocIP2gVJ68ygtAOhIBlCdDToXBrRV +s6CgAHwIJ7nXQ8KKbVgRDsvZoMgG9fFBbQFQuwjEhm0DRz7uCdTnh20PhR0JBetBwbrDsKNjqN0g +BCb2TBMTkwZgqSICtBvUXf8PLOm+ysvL7wOGU0p8fPwbpJ7eP4AAwjcQBFqAA1rF8BLYGzgOTE0u +oAClxk5IagFQfzw8PJwhKCgIfOwsMNWTnKtx1eEwNqx4hx1uBDvgCLYdHnacJag9AcPIEY9vDASU +KEDVDzCCzCZOnBgCGiEERgzJI4TQRiSzoaHhNFNT04S0tDRW0FlFoARpbm7OePnyZV5glegPbNR7 +Aruuuc+fP58DLf1/AQQQzgSA1Bh8O2/evA3u7u4uIM9TY28gpQCU86ZPnw66bIXo3glyRMOKcljO +BuVoUOMPVH2ADlkDHfEFakMA++vgfj6ozw/SB0oIsLOUQIEL6haCIhA0wgeikTeDEzvwRekIIbTb +zqaurj4TiKOAPRcW0PEloMQHWk8Nqg5B7gFWMaBRSmZgKQ6KPNCarp+ghAMQQIRcCFukpbts2bJ+ +S0tLLVBjEHa501AYuUPvjoGOKwIN6IAwMEdgRAao8RcREQGOQFgVgNyaB+Vo2CEYoEiHnQkBuxSX +nBFP2AghMLIWBAYGgq5DfUtMKVBYWOgKtHtzZGQkE7AtwSIpKckIa+OAGr6ghAyK/BkzZoCOdfoH +jLsZwEQB2iUEWqYFag1/AwggQlkZtkTpNbD+2KOvr68FKv4Ge28AuZUOammDLgIGHfQDO10I1LVD +BqCtF6BhXNg5+MjTwrD6GnY7Kqw1D8LI9TslQ92wEUI9Pb0EYNtlKTC3HoN2DXEW90B1icASaFZU +VBT4wCLkk59BpRdoAAvU4wF1e4Hs/8CcvwMY+aCl5YLQOAUfJQEQQMRuFH6/aNGi/cAGRAzQoUKw +Ix8Ha44H5XSge8FHRoIOMwDlVFBggA43gwFQ9w90tT3oiEnk1jm2xho6Rk4c1JjjAOmHHZYILIFa +gQkgGBjRv9AbhNDinhWY42uA3dUaUMIFlsrgHWQwAGpUgo7wApUooAEs2CAUMOH/grbrQBjUgAGZ +/Q8ggIhJAH+hgxTf9+7ddUdGRsYMdizOYCoFQJEPyu2gIzJBI3pKSkoMLi4u4HvPQUd2woCWlha4 +iwg63AU54tFzPKzIhyUqbA1HWDVBjURAqEEIOhoUSLED3T8Z2F5JAs2cnjt/Dlx9gA6rAw1agfwD +mo0ERT5oTxVo/gJ0zzuwRAB5AHTkD2j1PmiZ8WdonP4FCCAWPEPEoP4eb3SUY9J3ibjGx+/52bdc +uckQ/AXSBQLVewPdGEQexgWd3Adq9IC2E4HugwYV+6BzHGEAJgY6zgi5yIZFNnp7AUbDqhPIMQmI +kTzkrh1swIfSRICrQQiLfNCwMTBidUE7Bt3c3cEnBcDAnIXzGXZs28HwH+hufz8/8FZK0IWcoHMj +GSB3z7yGRv5HaPUCKmH+AQQQC1qDD3QcOV96VlTPE664yM//xBgfg5M+sJ/L/h6YJIQYdh+7wRDq +xQ926GCYDQSdXgg6px6UIzw9PcFFPbDHApcHRdTmzZvBp5gin0qMbSQPNl4P4sOuhocV0bC6H1T1 +wc7GofbQOMhMUCkgJCQksnr16srQ0NBKYOSDimvQriye6OjoBGAjUR7ov19AdfABmWWrVzKcPH6S +4Sewd8QDrEZAp7aCzssFRj6oNzEJ2p0HRfwXaKICVQPgYg0ggFighvNlFOVvvc0YZv77Pyd4LwbK +anRGoGdZOMA7nvaeeczg4/gd3BWDtXwHCoBOZATduGJrawsu0svLyxnOnTsHlwctygDleuSiHHly +BuQHGIaN6sFyP6zBB/Ij7MZ45HO/kBt/1FzrAGsQAtsmKcB23kpgewB0KSMjsHuXAaz704ENcR7U +yF/NsH/vfnDjVglYDYAOcAMd0yssLPwNKDaXAbK95hU093+CFf2wqgUggECuBu3ikOHnZfA0Sz00 +4ScDD/Y69t9fhl9f3zB8fX2LoTpWjcHKRAvc+KB1WwCUw0ErbUBHboP666ChXdAxvLBxfFBktbW1 +YbTsZ86cyZCamgofwkUfyYNhUHUGy/WwuhgUwbBGGQzDunrIgzu0WrkEGyEERtIpR0fH6IKCgqT4 +uPhYdQ01EU5OLvilEUtWrmQ4CAybN69egaq+v3///Pm7b98+UAJ4B9S/mgGycRx0bCjo0FjQLjvY +2el/YAkAIIBge5FAFzEoA7FVQMma/nf/lLD67M/Pzwzf3z9k0JP4xFCR6gzueoBSK7USACiiQBfK +gCIblENBkQ27OQPWvQEdQwqKbNDp+/hGCIODg+E3dIAiHnYvC2jmDzThA+LDjiyHHYIFq4NhGDni +kXM7PQDIraA2zbp168+7u7tJamioCXBxcXPAjnpYtGI5OPLfv3nLoK+n9xcEDh8+/P/OnTvPnjx5 +soEBcnrAIyh+AY3878iRDwIAAcQCLexBRwmBtiD+2tATkhhd2Dv9MaMjF0YdxcIO3uh66tZzhvcf +P4NP6oKd9E0uAKV0UGSCIgY0IwdrdIFGrkCRTSoA3UYGGhqG3U4CimyQ2aC2AYgGBSzsOFdQZMKG +cUERDvIPKMFRY3CH0owAsvPmzVsMAUGBhlISEr+Bkc8Ki/yFy5YwHNh/kOHDu7cMBnr6f4DhBY58 +YO/gLjDyQXUeaFMx7MzcV9D4/Y5c9MMAQAAxorFBZ8yBLunSi80unfaQPVIErSJg+P39A8O3t/cZ +fI2ZGeKDbMClACgRkBJAoFwJGnYF5UJQZIOOogZFHHK/GHTlA2gWz8PDA9yyB/XniRnbB0UsKIJB +RT0o0kELWkAYFPmg4h5U1IPMh43mgSIcNHoGinzki4oGIuKR7xXaC8zdoKFoSdDIKycHA/QQHYZ5 +wAbeoQP7GT4Au7z6unp/gHr+AqtIUORffvr0KSzynzIgbr3+jF7vIwOAAMLmO1B5CxpW0guNDmx9 +KV6Lcubevz/AxtLHpwxsP+4xzKzxArcDQDmXmC4hqH8KGmsHRcSaNWsY5syZAxYH5T7QGeOgG6ZA +/XdiBnuQu23I3TdY5INyPigBgDAo14NKA5A62A0VsIgHYViuJ3UcnxaR/+3bd4YdO7YzGBgaAds4 +kgzcnJDMBTqAYu7ChQwHgdXfZ2CC1tXR+QN0Jyjn/wOG6Vlg428zNOKfMiC2FYNa/T/xHSgBEEDY +Yu0H1JDfq5euL7K1vZXNaLrYD55imIG5g52X4dNnbobj5+8wuNnxEuwSglqooBwPKupB9yyAgLq6 +OngaF7nLhmtYFxY4sEiGdduQaeSLqWAte9iULayBB8rZoFwOyu2g9gUo8kFuh1VjtO7W4pq3giRm +0FHM34Fd1k0MVpaWDBKgkpWDE9xCA3Xk5wJ7O4cPHQAdl/bf0FD/79cv3/+ePHXiH7CRfOzli5c7 +oXH2BGmw5wu0r493azZAALHgmQoGpaLfhw9f7VN56vJcLnBb+p//bOAz2ZhZucAHX+w5+YjBxkQd +5xWroGIX1E0DXWUCatiBWu2gC7RA3TNiFl8gT8fC6nQYBkUsSAw5ASAP4sDEQGbBJnBgK39gkQ/i +w7p4lDbuSF0yCTtg8Nfv/wxff/xl+PDpK8Pxg9sYbGxswYcBgop9kPyP/38ZFsybD2z4HmT4A/Sz +vr7e35/ff4HOz/h/7+69Y69fvd6JVN/DGnuwyCe4BxEggPCV23+gdciVO/feLbjTa/HAu2Rr2+d/ +kozM4MYgH8OVR88ZHj97Db/2BXmxyNatW8F1OAjExcWBZ97wzR8gT+Ag52RYLobNw8O6bLAEAksw +yO0H5BE62KgdyH2g3I5c38OmtglFPrXWwzJCT46DHbf5+88/8JF4X4F+O3pgK4M1MOeLiokwwHp6 +34D+nD8fmPMPHgKfKWhhYQlqzzCev3D+77lz53a+efPmKDDMnqDl/K/ERj4IAAQQMbOBoBQFGhv6 +sbXH+1VYybwZLxj0WZnZeRjYuIUYth+5xaAoJwmOGNhiEdDRdqALkUGrdEDXbBAzXQuLdNiiC1gf +Hbb4AjYsCzu2F3ZgM6ENKOgDOrArOZHre1oteIY5A2T+j98Q/A96NvDPv/+A/vvD8PHLV4ZH148y +uLm6Aksnfngm+gRM9AsXLgBHPsggcxMTcHg9e/6c6ezZsweA7alj0JwPi3xYzv9Nyu5jgAAi9tRc +0AgS6MSLX6t6khKj8xqmPWRx42PhEGA4eOEWQ0IApM6FzQ+A7kjEt1ADFvGw4h15cAaW40HisEkY +WA6GDcXCpmOREwGs/sbMzYjZO8yJH9pEPiP0pEDQ6X/gIxL/wU4U/A8+Dfj3b9BheX8YfoCOPr53 +msHezoaBm4cbHvnvgI3WRYsWMhw5dJiBCajRzNKMgYWZheHalcsM33/8YRQRFfsKTABvGBAnBcJy +/m9St54DBBAjiWpB3UTQ2S96EQkx3Q/Y45S+vr3LEO8kwBDkYQ7uEYASAa6GFPJwLKyIB0U67BJN +kBhs/B2Wa2Fr7GBj8LBIhyysZMKYxcM35YpMUz3SGSCRDiraYQcBgxMBMMJB9Tz85GRw++YPwzeg +v5/dPgFs8JmDqyYODkj1+PrjB4bFixYzHDl8mIGTg43B3sYe3Ja6desOw2+gefwCggw83FzfWptq +QRsULkO7e2SdlAgCAAFE6kD+b6hln65cuHRGT/qpxncea6lXL54xOJrKwxdCYgtkWB8dlLNBkQ0b +lQPRoIQAu0QQ1B0D1dNCQqA7dEWQWut8SMuuQPdssqHM3eObv0fG1MzlsMOTwcdhgs4J/QmJfNDx +9yD8/Tfk7G+YeuTI//DkAoOdnS3QT6C1FZCc//ztG4ZFCxcxHAW2lziACd3F0QnYTvjDcOPmbWAY +/WQQl5BkkJGRZZCRlmI1MTFh3rdv7y5oO+0XuUvKAQKI3BABDf2BBol0NdQls1g0SvwbknQZzI00 +wddooDf2YPU8YnQOMQYPm09HXlGLXEcPto2lIGeAzjr9CT0zHcT+BT75Fpg7oPU7NqeCMwAw8n98 +/cLw7M4J0A13DLygYXQWZgZxYWGG+0+egIewjx45wsAJTNzOzi4Mf//8Zrhw8SIw4/xlkJaWZJCT +lWOQkQVmNB5+0DUmf50dLE1AVTMw8r+Q6x+AAKIkVEHtB9DyImNWFobQjPLJSbnx7sBqQAKcU5Ej +DP2CeORVtbCiHrmIH5SRDj/iGMKGHIH8H3zOMy5Xwq5QAB2qyQwsPH///MZw/tR+BiUlZXBiOHnm +NMNnYPX3BZgoPn74wPD502fwnLwtsCsICi/QzCbo2HQxcSnw5JeCvAKDvLw0g7CQAMOf3+CdTmfs +7OxAYzSvyD09FCCAKA1hkP9A65GsgUV34PHjJ6JAq1NAfW1YNwx5QwX6PDusBQ9q5MH64oPhbABY +d+3PP8hBwKCGHOj6hp/QRhz0VHeMiIcc9s3IwAY6RRVYqrMxQY6C//3rN7DE+8pw8exhYOQJgi8I +uH7zOsMXYCkIvnkNiEG3IbABw0JPVw9s+K1bN8CXFcnISDPIy8kDc74cg5gE6IYmEQbQOZzfgI4C +jazu2Lwqpam+cjUwAXwix68AAURpaP+DTjZcBjbmDt27dw982xLyTciwljlshwzyxAtsxo3Y/jit +Ix3cev8LOt6ageEtsFB99ekf+BToN5//MXz4/g/coEPv3oEii42ZEXz3hygvE4MwDyP4PHEWYOSD +unygYvzPr68Ml88fAUaeADjSL127DOwh/GJ49+EdeE3DV2A7iBNY8oEi/y+wSnzy5DG4lBERl2YQ +EpNn4BKWZ2DmkWL4xSLM8PEPN8OPf6wMP/8D21qsPAy2Tt49oOoYupGHZAAQQNQI8b/QRHBtxYoV +20GtetgdpMh9ceTtUrB5dXoMvxIzGgfK6V++Q+4rewmMdNDB7W8+/wXfXQYq6hlhuR0pwvk4IXcb +ifBAIh90ODxIEYgGXfYkxM0ATAh/GP79/sJw6vgh8GAZqLdz4/ZNYCn4h+Hp86cMTx48YvgFDCte +8FpAefC8BehiiJfvvjFwC0oyCIorALE8A+hsZm5+YciFdMCeAeSKIdDN19wMn/7xCkyau6YWNKVC +zi5jgACiVsiDmrGgBWpmwGpgAbC+YgdtI8M1TYwS3/8xXfEfS0MKXQybGhSz/iNu80DhQ5WBDrMH +Fe+gbhuoLod11ZBzN0w9GyvkFi9WFkYUp4IOx2cHi0PYoIQEOigfVMT/Bub8Xz++MFw8f5aBm4sL +XNdfv3mTgRGoEDQ3Arr27BuwMcwPLAVBRTzILlDv4MXbb8CiXhKcIBTk5RkkJaUZePgEGX4zcTF8 +/8PK8OUXpDriZmcEJs5/DN+/fmT48uHt31gvTV3Q4g9gVfCNlIgDCCBqreoEzR2A1pw9OXXq5Glh +YSEbXl4eBhZW0C5YRshFGv8gl+OAijbQlSiw2wL+/oXcRAKuLf8zgtWAAuM/9H4qBuigCuwseiZo +1wt2NRMT9Daif9A7msB3VcEqcQZIfQyrWVjAF/NArmT59RvSgkdOM7Dj30GRycHGBG28QYo4UAYH +JQA26A0p4ET0B2QeyC+QhAG+RAAo/wvYL/z44QvDpfPHwLkbVMzffvCAgR2Ye9++e8vwCHT7GTC3 +CwG7t7LAbh24ewy6DhpY9ygBG3kikgoM3MKyDF9YJBmefONnYP/PCUyELODBpE/A7ubrj0D8CZT4 +/jPcf8HO8P0LO3P5xP2LOvMd/YClwE9SGoQAAVg7gx6CYSiO/4sEkxEjNjvgS/gwvpOvIOLuzNXd +wVEiMTcO2AxLNMO0fR2uEocemiZNmn/z3vu/NP39M/bKByQdMbrT2WJYqdrMrFgiCuTeQLBUlu/u +mxQ6TiEk4oRSR+WmnsTXUUIn9B8/vsRn+kIkTC8yEovIbNLzE7tDYqrImol5hr2RFkponfdTpld6 +UdT+6v//D/JK4nFojaGQT1DSeKv4Qc6AikUiTF6jC/beXNU3fhBguV7BKBrwjz48b43zKUTTbijw +Ib9xYSljbLYhypaLmtOG7bZg1R1kClWE3MDulBUpSdOg2AeyZIpaQ/Yf7jwCjw7gy0FvPOpPfikI +XwKImuu6f0CHJJ8+fXz/wR8mXsXfTDwMzMBQ/AfNdX//IW6bQekv/0esQWVEaoVjqMNeY0DrA9S6 +AFFF/IcnOlAigJUW/xkQF7/Brv+B3W32FzpCxsyMsBtUt7Mywdo0kMTBBG0cgC6KAJU8v4Fds2/A +Bt2rB8DI5+ECXwVy/fYt8DD250+fQBc8M7wHJgJxUVFonf8JPMDz8M0vBmExaQZOIXmGL8wyDC9f +iTP8fsMPbO1zgOt6ZmgpxobWYgNFvpQgE8PTd5wMzL+B7QiTyBkMC3sMgaXAD/Q7knABgACidusL +tB9bxcTcxj+pdEqdsKgEsKUvAGzhM2EclI5SCqDX4wyUXUdG+8UbiITxF5q6/v35BayPPzNwfzkP +vujuNbBrd+XGVWDk84AHve7fuwe+8lBESBi8FgI0FvL563eG07eB+YZTioFdQI6BV1iOgUdAnIGD +W5CBhY0TGOks2EeVkNzBDE0UX779YPj77Q2DEtOJvtbyuDZQZiRmdBAggKi9swO8m/jMySNnU/+8 +//zzBz8vByc3+GozYiP/PzHTskh9cNj9NOCSA6k9ALu2EXZzIUwvuJ6H5nKG/6hdQORr4KCFA+SW +M6g5DFA1sO4TI/RGwN+gCa2v7xj4v19lUFJWAq9aBk3u+P8PYti0eRP4mufHjx8ySAH78ZqaWuD7 +L998/MFw5NoPBl4haQZeEXkGHiFZBi4+cWDDHphhQHdtMDJjRD6sBAUJg25aFONnAnY9GRjkREGT +WtwM/37+ZvjxxSQfqHQWNC6+E4owgACiRf8LdNWDenZhdam+fWSgELAU4OLmBde/yJEIrsuRingm +eEQwQu/Y/A9udIEaVsyMSA0+RsiVdCxMsMiFVAqM0DodcicXpEEJa9QxIl1kBBcDLXj4zwC92Q0S +o///wa61Q5q4+Q9xNxO0OgG1ARABB7rf7yfDlJ46hucPb4BXItvZ2QEjn5fh+YvnDAcOHWI4euwo +w7PHTxjkgInCxNgEvD7x8cuPDOcf/AdffccL7ONzC8owcPGLM7BzCTAwA3M+sKUCbNZArtAD9UD4 +gd1KcX5GBlEg5mUHNUb/gy9j+gdeDgdZ/AIab/j1E9ie+PGNgf3Hw21x4V5JoLklQrODAAFEi71d +4FJgan/r6lk2gX6/fnxn5uHmAqZYFgZ2ZkhLmgXauobVoUxMiEiBRdR/2DJIRuyLMuANSgZGlJQM +0/sfaaQKXM//Q5QU/5mQruWGDdn+Q1IPbRWC3McCvdIT3EYA8llZGaFtDFDk/2J4/uwlw7wZ/eB6 +HtSaBxX3sDGOH8Cu3/tXrxnMTM3AmzZA3b+bD14z3H7NgYh8YGufi1eMgY2THzwgJsjDxCAh8B+Y +s/8BI/sv+D61nz9+gRuKvz78ZHjx+yewxIFgJoY/DOwM3/68f/Xg04M7116fP3v6PrAXBrqUBrQ7 +hgfaM8N7+BRAANEiAYC2I4GWIT///ebqVTEpPj0R3j9Az7GCh0n//8cs6sGlwX9E5CNyHFoxzAQd +V4eWAuAWMTP0qkKkRASyB3SRLKjUgVxmCb30khF+gxHYnj/QIogZGMvg3shfyAW2sCvPwJdc/4a0 +vkFXG4ISL0ju3ee/DE/e/GR49e4Tw5YV88Dmgep10A4l0CAYqNsH2phqb2/P4O/vD96rD9qxu33/ +GYY/PGoMXAKSwFwvxSAiIswgLcHBICX2i0GQ6y3QDX/AufjHO6DZb/8wfGT88ffTm8ef79+58vrC +udMvjh879hwaod+hGe0bdHb2CzSyQYtC3kIH5t4yoF20gw0ABBCthuBAqU9JRlbOccbCLRNExMQZ +eICNQSZQbP1H3C0NijjYXZOgVjUogEFKQGxYVwdl3Pk/JIJAd9SBIu8ftA/+9z9kfAHUJYPdZghK +JGB5aGMAfMcltBvIAG0rgIZrQXdeguz/D78Z9T+YD6vz/0LNff3pP8ODN//ALe+Pn38y3Hn6heHW +/dcMW3pcGfh52MF7EUBL5EEJABT5IDbotLGHwD4/GxsHQ3nbPAYuYNUgJirCICslBox0gX/MwM7b +8yf33ty4dvn5yRMnnv38+fM7lsj9zIDY2/eZAXGhEEztD+g0PQz/IWVqGCAAbWewgjAMg+EyC3pS +BnrydXw194bzsOMUEaZDRTdmm9YkbezAq556Lfz52yYh/f413ksbaw/7ulL9qcln89V6ucBcOHX4 +nA+FFOJnykrERRFRHluTLKRgGu89zc5Wn2CZor11pr4iRWoF3oWikyCuYYS0JGGfjKxMxNcBAgzd +R6Kzxfv+ZRwH3QVdXx0tOt+oDo922595PsKZDp2/4TY4tbZpQJXKvvT5FnX0tkVx25XlFQAe8WQk +ZzYqQU3b6Nz7SHQReIiiykw//Bo28RZAtEoAf6HF0ps1q1esj0stSvv69yuwMQhausUEabAxQe4Q +B12UDrqLmA+YOFiYGbBGJCRRMIJzPijyQJH47wcoIv+Bb7IHzdD9/c8AH0kEJag/0NwPHkz6C6GR +hh3ACewvtG5hBDakgOUFuEH1B6j5/79fwAbWL4bHr38x3H7yneH1+x/gbh4z4y8GEa4f/7m/P/j5 +8uGFj7dP7Gc2MTERAZ0IDlrHACryQQ0yUOSvWrXqxYoVKx5CI/0FdPkWiA+76BW2hu87tKj+MxA3 +iQAEEC1nYWDHzBmePHlqmaysDBtsfgA0/PsbWrT+/ou4ffcndFEFePj4P0IOrB46nAzr4kE7Coiu +IAN6V/A/9Cpx8NgiOJKB2RW0swUoB4xgYGPq31/QTN1Pho9ffjB8+fETfOPnr69vwcX2nVs3GW5c +2PPx/r1H95Dq1jfQnAqKtP/Aer/Cx8eHE5QATE1NYUezvC8pKTkC1QO72Re2OfMlA2J//u/BcHUM +QADR8oQH2PzAqz37Dx0xsfF24nnPycDGzg0dj4dE7p9//+GLJv/C+/T/4d035L4+A3w+ADpDB6KB +EczE+JeB6T+o7Aa12H6B8e8/wJbyT9A28J/gSGYElqCf3r9luHv/IcOVG/cYrt1+zPDl22/wfkcQ +Bu114Gd+8efx9f1XP378Cbql9DE04p5Bi+wP0OIZ5BJuYMRnAxt4nKCt2KAEA8z5PwsKCtYDq4Ef +0ITyHJrrnzEgVu1+hYbL38FwWQQIAAQQredhwfMDHJyc5v2Lj8zjFRBn4BUQAq9wRYlc2OwadPiV +BdSCByUCYN+MmfEfPOf+h0bsH3A36DfDDyANajUzAiP/88d3DPfuP2C4fus+MHKfMLz/9B18cSkT +KwcwgjmBEcwBub2VjZuBhY0HTLMBO9kiP3a/37VxLWg3Leh2x3vQiH/JgNhQ+QdpvIqFiYmJz8/P +b0JKSko0sMvHdOzYsX9AfP4UsP8FVf8GKeJhW7Q+Q+vzP4Ml4mEAIIBofcYLeH7gx/fvj3+9v3vn +Hw+vCjsTDwMX9KZ5pv9/wZH3Dxi5oCVOf0B93O8/wf1r0PIxEP7/H7SO7hP4HL9rN+8zXL35iOHt +x2+QLWosHOAIBl3JC8agyGWXYmCVVmWQVOCCyEHVMDEDczow4fGyvv3PcHvipZ3rD69ggNxlirF3 +HsdINDM3N7coMNfPiYmJ8fj48SPTyZMn/+7cuXMjMFIvI0U+LOJfQyMeloj+MQxCABBAtE4A/6DF +3tvVi6YsLavrq//74TvDuz+/oQtCgXXw98+/nzy6/f761cuvTp449uzmzZvvYMUkdJ2BhIZdotNf +NklgnIsxsEgqMkjIQSMcnLs5IMU4Myuw/geWLEwgmhmImeAFnCTDsV/nNjVsvn3nzQEg9wEDYjMF +/MQMAqUkyDBOaWnpCmAR73rgwAGmT58+/QFG/hxgwrwJa/BCzYSVHt8YEDd/DtqpDYAAYqRTIgOd +PK4FxAbQhiEb2iAGbCADdo4NrBsECnhRINYMzp3Y85LRnA09crFaCGyti39aCLq1eCG0aH8IzZmw +7dKkXMkKPqBJSkoqRFhYuB/Y0BN8+vTpdGBVcBOYGH5CzXsNjfg3aIkKI+IH2y1tAAFEr7VY7NCZ +QtAqYg5o4MPOyP8JzfF/YH1dpICDHWEDOrBfPyavevojlmCsx32DLif/d6Pr4vYtB5dDc/ljIot2 +fIAJ6nbQhcZmQJwKxCsZIMviGdByPnJdjzNxDbYEABBAQ+Hwf0ZoogHvSIpMiut+KlCgDCnaTwCL +9jpyi3ZiSy/QbijQETrC0ATMA3XTD6SBnY9ILXy8JctgSwAAATSULgIC5UTQZhR5aJXCBA3852QW +7cSEDTM0AYBKIW4oZmVAHJ4Ji/gfxJYwgy0BAATQULo69ic0sl9DI+Y/NND/0qiR9R+amGAN0p/Q +CGeAjdwhVVv/GQb3GhacACCAWIbY1bGwCKEL0NTU/A+1jxGaABiRIvs/NEcP6du0AAIMANtMxR3x +N38FAAAAAElFTkSuQmCC\ +""" + +def thumbnail(): + icon = base64.decodestring(iconstr) + return icon + +if __name__ == "__main__": + icon = thumbnail() + f = file("thumbnail.png","wb") + f.write(icon) + f.close() diff --git a/src/odf/userfield.py b/src/odf/userfield.py new file mode 100644 index 0000000000..501435878f --- /dev/null +++ b/src/odf/userfield.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): Michael Howitz, gocept gmbh & co. kg +# +# $Id: userfield.py 447 2008-07-10 20:01:30Z roug $ + +"""Class to show and manipulate user fields in odf documents.""" + +import sys +import time +import zipfile + +import xml.sax +import xml.sax.handler +import xml.sax.saxutils + +from odf.namespaces import OFFICENS, TEXTNS + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + + +OUTENCODING = "utf-8" + + +# OpenDocument v.1.0 section 6.7.1 +VALUE_TYPES = { + 'float': (OFFICENS, u'value'), + 'percentage': (OFFICENS, u'value'), + 'currency': (OFFICENS, u'value'), + 'date': (OFFICENS, u'date-value'), + 'time': (OFFICENS, u'time-value'), + 'boolean': (OFFICENS, u'boolean-value'), + 'string': (OFFICENS, u'string-value'), + } + + +class UserFields(object): + """List, view and manipulate user fields.""" + + # these attributes can be a filename or a file like object + src_file = None + dest_file = None + + def __init__(self, src=None, dest=None): + """Constructor + + src ... source document name, file like object or None for stdin + dest ... destination document name, file like object or None for stdout + + """ + self.src_file = src + self.dest_file = dest + + def list_fields(self): + """List (extract) all known user-fields. + + Returns list of user-field names. + + """ + return [x[0] for x in self.list_fields_and_values()] + + def list_fields_and_values(self, field_names=None): + """List (extract) user-fields with type and value. + + field_names ... list of field names to show or None for all. + + Returns list of tuples (, , ). + + """ + found_fields = [] + def _callback(field_name, value_type, value, attrs): + if field_names is None or field_name in field_names: + found_fields.append((field_name.encode(OUTENCODING), + value_type.encode(OUTENCODING), + value.encode(OUTENCODING))) + return attrs + + self._content_handler(_callback) + return found_fields + + def list_values(self, field_names): + """Extract the contents of given field names from the file. + + field_names ... list of field names + + Returns list of field values. + + """ + return [x[2] for x in self.list_fields_and_values(field_names)] + + def get(self, field_name): + """Extract the contents of this field from the file. + + Returns field value or None if field does not exist. + + """ + values = self.list_values([field_name]) + if not values: + return None + return values[0] + + def get_type_and_value(self, field_name): + """Extract the type and contents of this field from the file. + + Returns tuple (, ) or None if field does not exist. + + """ + fields = self.list_fields_and_values([field_name]) + if not fields: + return None + field_name, value_type, value = fields[0] + return value_type, value + + def update(self, data): + """Set the value of user fields. The field types will be the same. + + data ... dict, with field name as key, field value as value + + Returns None + + """ + def _callback(field_name, value_type, value, attrs): + if field_name in data: + valattr = VALUE_TYPES.get(value_type) + attrs = dict(attrs.items()) + # Take advantage that startElementNS can take a normal + # dict as attrs + attrs[valattr] = data[field_name] + return attrs + self._content_handler(_callback, write_file=True) + + def _content_handler(self, callback_func, write_file=False): + """Handle the content using the callback function and write result if + necessary. + + callback_func ... function called for each field found in odf document + signature: field_name ... name of current field + value_type ... type of current field + value ... value of current field + attrs ... tuple of attrs of current field + returns: tuple or dict of attrs + write_file ... boolean telling wether write result to file + + """ + class DevNull(object): + """IO-object which behaves like /dev/null.""" + def write(self, str): + pass + + # get input + if isinstance(self.src_file, basestring): + # src_file is a filename, check if it is a zip-file + if not zipfile.is_zipfile(self.src_file): + raise TypeError("%s is no odt file." % self.src_file) + elif self.src_file is None: + # use stdin if no file given + self.src_file = sys.stdin + + zin = zipfile.ZipFile(self.src_file, 'r') + content_xml = zin.read('content.xml') + + # prepare output + if write_file: + output_io = StringIO() + if self.dest_file is None: + # use stdout if no filename given + self.dest_file = sys.stdout + zout = zipfile.ZipFile(self.dest_file, 'w') + else: + output_io = DevNull() + + + # parse input + odfs = ODFContentParser(callback_func, output_io) + parser = xml.sax.make_parser() + parser.setFeature(xml.sax.handler.feature_namespaces, 1) + parser.setContentHandler(odfs) + parser.parse(StringIO(content_xml)) + + # write output + if write_file: + # Loop through the input zipfile and copy the content to + # the output until we get to the content.xml. Then + # substitute. + for zinfo in zin.infolist(): + if zinfo.filename == "content.xml": + # Write meta + zi = zipfile.ZipInfo("content.xml", time.localtime()[:6]) + zi.compress_type = zipfile.ZIP_DEFLATED + zout.writestr(zi, odfs.content()) + else: + payload = zin.read(zinfo.filename) + zout.writestr(zinfo, payload) + zout.close() + zin.close() + + +class ODFContentParser(xml.sax.saxutils.XMLGenerator): + + def __init__(self, callback_func, out=None, encoding=OUTENCODING): + """Constructor. + + callback_func ... function called for each field found in odf document + signature: field_name ... name of current field + value_type ... type of current field + value ... value of current field + attrs ... tuple of attrs of current field + returns: tuple or dict of attrs + out ... file like object for output + encoding ... encoding for output + + """ + self._callback_func = callback_func + xml.sax.saxutils.XMLGenerator.__init__(self, out, encoding) + + def startElementNS(self, name, qname, attrs): + if name == (TEXTNS, u'user-field-decl'): + field_name = attrs.get((TEXTNS, u'name')) + value_type = attrs.get((OFFICENS, u'value-type')) + if value_type == 'string': + value = attrs.get((OFFICENS, u'string-value')) + else: + value = attrs.get((OFFICENS, u'value')) + + attrs = self._callback_func(field_name, value_type, value, attrs) + + self._startElementNS(name, qname, attrs) + + def _startElementNS(self, name, qname, attrs): + # copy of xml.sax.saxutils.XMLGenerator.startElementNS + # necessary because we have to provide our own writeattr + # function which is called by this method + if name[0] is None: + name = name[1] + elif self._current_context[name[0]] is None: + # default namespace + name = name[1] + else: + name = self._current_context[name[0]] + ":" + name[1] + self._out.write('<' + name) + + for k,v in self._undeclared_ns_maps: + if k is None: + self._out.write(' xmlns="%s"' % (v or '')) + else: + self._out.write(' xmlns:%s="%s"' % (k,v)) + self._undeclared_ns_maps = [] + + for (name, value) in attrs.items(): + if name[0] is None: + name = name[1] + elif self._current_context[name[0]] is None: + # default namespace + #If an attribute has a nsuri but not a prefix, we must + #create a prefix and add a nsdecl + prefix = self.GENERATED_PREFIX % self._generated_prefix_ctr + self._generated_prefix_ctr = self._generated_prefix_ctr + 1 + name = prefix + ':' + name[1] + self._out.write(' xmlns:%s=%s' % (prefix, quoteattr(name[0]))) + self._current_context[name[0]] = prefix + else: + name = self._current_context[name[0]] + ":" + name[1] + self._out.write(' %s=' % name) + writeattr(self._out, value) + self._out.write('>') + + def content(self): + return self._out.getvalue() + + +ATTR_ENTITIES = { + '\n': ' ' # convert newlines into entities inside attributes + } + + +def writetext(stream, text, entities={}): + text = xml.sax.saxutils.escape(text, entities) + try: + stream.write(text) + except UnicodeError: + for c in text: + try: + stream.write(c) + except UnicodeError: + stream.write(u"&#%d;" % ord(c)) + +def writeattr(stream, text): + # copied from xml.sax.saxutils.writeattr added support for an + # additional entity mapping + countdouble = text.count('"') + entities = ATTR_ENTITIES.copy() + if countdouble: + countsingle = text.count("'") + if countdouble <= countsingle: + entities['"'] = """ + quote = '"' + else: + entities["'"] = "'" + quote = "'" + else: + quote = '"' + stream.write(quote) + writetext(stream, text, entities) + stream.write(quote) diff --git a/src/odf/xforms.py b/src/odf/xforms.py new file mode 100644 index 0000000000..35eeeb971c --- /dev/null +++ b/src/odf/xforms.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import XFORMSNS +from element import Element + +# ODF 1.0 section 11.2 +# XForms is designed to be embedded in another XML format. +# Autogenerated +def Model(**args): + return Element(qname = (XFORMSNS,'model'), **args) + diff --git a/src/calibre/ebooks/pyPdf/__init__.py b/src/pyPdf/__init__.py similarity index 100% rename from src/calibre/ebooks/pyPdf/__init__.py rename to src/pyPdf/__init__.py diff --git a/src/calibre/ebooks/pyPdf/filters.py b/src/pyPdf/filters.py similarity index 84% rename from src/calibre/ebooks/pyPdf/filters.py rename to src/pyPdf/filters.py index 581cd52111..7fe10fb481 100644 --- a/src/calibre/ebooks/pyPdf/filters.py +++ b/src/pyPdf/filters.py @@ -34,6 +34,11 @@ Implementation of stream filters for PDF. __author__ = "Mathieu Fenniak" __author_email__ = "biziqe@mathieu.fenniak.net" +from utils import PdfReadError +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO try: import zlib @@ -100,32 +105,33 @@ class FlateDecode(object): # predictor 1 == no predictor if predictor != 1: columns = decodeParms["/Columns"] - if predictor >= 10: - newdata = "" + # PNG prediction: + if predictor >= 10 and predictor <= 15: + output = StringIO() # PNG prediction can vary from row to row rowlength = columns + 1 assert len(data) % rowlength == 0 - prev_rowdata = "\x00"*rowlength - for row in range(len(data) / rowlength): - rowdata = list(data[(row*rowlength):((row+1)*rowlength)]) - filterByte = ord(rowdata[0]) + prev_rowdata = (0,) * rowlength + for row in xrange(len(data) / rowlength): + rowdata = [ord(x) for x in data[(row*rowlength):((row+1)*rowlength)]] + filterByte = rowdata[0] if filterByte == 0: pass elif filterByte == 1: for i in range(2, rowlength): - rowdata[i] = chr((ord(rowdata[i]) + ord(rowdata[i-1])) % 256) + rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256 elif filterByte == 2: for i in range(1, rowlength): - rowdata[i] = chr((ord(rowdata[i]) + ord(prev_rowdata[i])) % 256) + rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256 else: # unsupported PNG filter - assert False + raise PdfReadError("Unsupported PNG filter %r" % filterByte) prev_rowdata = rowdata - newdata += ''.join(rowdata[1:]) - data = newdata + output.write(''.join([chr(x) for x in rowdata[1:]])) + data = output.getvalue() else: # unsupported predictor - assert False + raise PdfReadError("Unsupported flatedecode predictor %r" % predictor) return data decode = staticmethod(decode) @@ -220,9 +226,15 @@ def decodeStreamData(stream): data = ASCIIHexDecode.decode(data) elif filterType == "/ASCII85Decode": data = ASCII85Decode.decode(data) + elif filterType == "/Crypt": + decodeParams = stream.get("/DecodeParams", {}) + if "/Name" not in decodeParams and "/Type" not in decodeParams: + pass + else: + raise NotImplementedError("/Crypt filter with /Name or /Type not supported yet") else: # unsupported filter - assert False + raise NotImplementedError("unsupported filter %s" % filterType) return data if __name__ == "__main__": @@ -237,3 +249,4 @@ if __name__ == "__main__": """ ascii85_originalText="Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure." assert ASCII85Decode.decode(ascii85Test) == ascii85_originalText + diff --git a/src/calibre/ebooks/pyPdf/generic.py b/src/pyPdf/generic.py similarity index 90% rename from src/calibre/ebooks/pyPdf/generic.py rename to src/pyPdf/generic.py index 69a9ad7b5e..fb75ef3b3f 100644 --- a/src/calibre/ebooks/pyPdf/generic.py +++ b/src/pyPdf/generic.py @@ -203,6 +203,10 @@ class IndirectObject(PdfObject): class FloatObject(decimal.Decimal, PdfObject): + def __new__(cls, value="0", context=None): + return decimal.Decimal.__new__(cls, str(value), context) + def __repr__(self): + return str(self) def writeToStream(self, stream, encryption_key): stream.write(str(self)) @@ -419,8 +423,73 @@ class NameObject(str, PdfObject): class DictionaryObject(dict, PdfObject): - def __init__(self): - pass + + def __init__(self, *args, **kwargs): + if len(args) == 0: + self.update(kwargs) + elif len(args) == 1: + arr = args[0] + # If we're passed a list/tuple, make a dict out of it + if not hasattr(arr, "iteritems"): + newarr = {} + for k, v in arr: + newarr[k] = v + arr = newarr + self.update(arr) + else: + raise TypeError("dict expected at most 1 argument, got 3") + + def update(self, arr): + # note, a ValueError halfway through copying values + # will leave half the values in this dict. + for k, v in arr.iteritems(): + self.__setitem__(k, v) + + def raw_get(self, key): + return dict.__getitem__(self, key) + + def __setitem__(self, key, value): + if not isinstance(key, PdfObject): + raise ValueError("key must be PdfObject") + if not isinstance(value, PdfObject): + raise ValueError("value must be PdfObject") + return dict.__setitem__(self, key, value) + + def setdefault(self, key, value=None): + if not isinstance(key, PdfObject): + raise ValueError("key must be PdfObject") + if not isinstance(value, PdfObject): + raise ValueError("value must be PdfObject") + return dict.setdefault(self, key, value) + + def __getitem__(self, key): + return dict.__getitem__(self, key).getObject() + + ## + # Retrieves XMP (Extensible Metadata Platform) data relevant to the + # this object, if available. + #

            + # Stability: Added in v1.12, will exist for all future v1.x releases. + # @return Returns a {@link #xmp.XmpInformation XmlInformation} instance + # that can be used to access XMP metadata from the document. Can also + # return None if no metadata was found on the document root. + def getXmpMetadata(self): + metadata = self.get("/Metadata", None) + if metadata == None: + return None + metadata = metadata.getObject() + import xmp + if not isinstance(metadata, xmp.XmpInformation): + metadata = xmp.XmpInformation(metadata) + self[NameObject("/Metadata")] = metadata + return metadata + + ## + # Read-only property that accesses the {@link + # #DictionaryObject.getXmpData getXmpData} function. + #

            + # Stability: Added in v1.12, will exist for all future v1.x releases. + xmpMetadata = property(lambda self: self.getXmpMetadata(), None, None) def writeToStream(self, stream, encryption_key): stream.write("<<\n") @@ -563,7 +632,7 @@ class EncodedStreamObject(StreamObject): return self.decodedSelf.getData() else: # create decoded object - decoded = StreamObject() + decoded = DecodedStreamObject() decoded._data = filters.decodeStreamData(self) for key, value in self.items(): if not key in ("/Length", "/Filter", "/DecodeParms"): @@ -583,8 +652,8 @@ class RectangleObject(ArrayObject): ArrayObject.__init__(self, [self.ensureIsNumber(x) for x in arr]) def ensureIsNumber(self, value): - if not isinstance(value, NumberObject): - value = NumberObject(value) + if not isinstance(value, (NumberObject, FloatObject)): + value = FloatObject(value) return value def __repr__(self): diff --git a/src/calibre/ebooks/pyPdf/pdf.py b/src/pyPdf/pdf.py similarity index 86% rename from src/calibre/ebooks/pyPdf/pdf.py rename to src/pyPdf/pdf.py index f64c1a6c22..ce4331b498 100644 --- a/src/calibre/ebooks/pyPdf/pdf.py +++ b/src/pyPdf/pdf.py @@ -88,7 +88,8 @@ class PdfFileWriter(object): return IndirectObject(len(self._objects), 0, self) def getObject(self, ido): - assert ido.pdf == self + if ido.pdf != self: + raise ValueError("pdf must be self") return self._objects[ido.idnum - 1] ## @@ -105,7 +106,7 @@ class PdfFileWriter(object): page = self._addObject(page) pages = self.getObject(self._pages) pages["/Kids"].append(page) - pages["/Count"] = NumberObject(pages["/Count"] + 1) + pages[NameObject("/Count")] = NumberObject(pages["/Count"] + 1) ## # Encrypt this PDF file with the PDF Standard encryption handler. @@ -272,7 +273,6 @@ class PdfFileWriter(object): class PdfFileReader(object): def __init__(self, stream): self.flattenedPages = None - self.pageNumbers = {} self.resolvedObjects = {} self.read(stream) self.stream = stream @@ -290,7 +290,7 @@ class PdfFileReader(object): def getDocumentInfo(self): if not self.trailer.has_key("/Info"): return None - obj = self.getObject(self.trailer['/Info']) + obj = self.trailer['/Info'] retval = DocumentInformation() retval.update(obj) return retval @@ -302,6 +302,28 @@ class PdfFileReader(object): # Stability: Added in v1.7, will exist for all future v1.x releases. documentInfo = property(lambda self: self.getDocumentInfo(), None, None) + ## + # Retrieves XMP (Extensible Metadata Platform) data from the PDF document + # root. + #

            + # Stability: Added in v1.12, will exist for all future v1.x releases. + # @return Returns a {@link #generic.XmpInformation XmlInformation} + # instance that can be used to access XMP metadata from the document. + # Can also return None if no metadata was found on the document root. + def getXmpMetadata(self): + try: + self._override_encryption = True + return self.trailer["/Root"].getXmpMetadata() + finally: + self._override_encryption = False + + ## + # Read-only property that accesses the {@link #PdfFileReader.getXmpData + # getXmpData} function. + #

            + # Stability: Added in v1.12, will exist for all future v1.x releases. + xmpMetadata = property(lambda self: self.getXmpMetadata(), None, None) + ## # Calculates the number of pages in this PDF file. #

            @@ -346,43 +368,39 @@ class PdfFileReader(object): # Stability: Added in v1.10, will exist for all future v1.x releases. # @return Returns a dict which maps names to {@link #Destination # destinations}. - def getNamedDestinations(self, tree = None, map = None): - if self.flattenedPages == None: - self._flatten() - - get = self.safeGetObject - if map == None: - map = {} - catalog = get(self.trailer["/Root"]) + def getNamedDestinations(self, tree=None, retval=None): + if retval == None: + retval = {} + catalog = self.trailer["/Root"] # get the name tree if catalog.has_key("/Dests"): - tree = get(catalog["/Dests"]) + tree = catalog["/Dests"] elif catalog.has_key("/Names"): - names = get(catalog['/Names']) + names = catalog['/Names'] if names.has_key("/Dests"): - tree = get(names['/Dests']) + tree = names['/Dests'] if tree == None: - return map + return retval if tree.has_key("/Kids"): # recurse down the tree - for kid in get(tree["/Kids"]): - self.getNamedDestinations(get(kid), map) + for kid in tree["/Kids"]: + self.getNamedDestinations(kid.getObject(), retval) if tree.has_key("/Names"): - names = get(tree["/Names"]) + names = tree["/Names"] for i in range(0, len(names), 2): - key = get(names[i]) - val = get(names[i+1]) + key = names[i].getObject() + val = names[i+1].getObject() if isinstance(val, DictionaryObject) and val.has_key('/D'): - val = get(val['/D']) - dest = self._buildDestination(val, key) + val = val['/D'] + dest = self._buildDestination(key, val) if dest != None: - map[key] = dest + retval[key] = dest - return map + return retval ## # Read-only property that accesses the {@link #PdfFileReader.getOutlines @@ -396,20 +414,16 @@ class PdfFileReader(object): #

            # Stability: Added in v1.10, will exist for all future v1.x releases. # @return Returns a nested list of {@link #Destination destinations}. - def getOutlines(self, node = None, outlines = None): - if self.flattenedPages == None: - self._flatten() - - get = self.safeGetObject + def getOutlines(self, node=None, outlines=None): if outlines == None: outlines = [] - catalog = get(self.trailer["/Root"]) + catalog = self.trailer["/Root"] # get the outline dictionary and named destinations if catalog.has_key("/Outlines"): - lines = get(catalog["/Outlines"]) + lines = catalog["/Outlines"] if lines.has_key("/First"): - node = get(lines["/First"]) + node = lines["/First"] self._namedDests = self.getNamedDestinations() if node == None: @@ -424,49 +438,44 @@ class PdfFileReader(object): # check for sub-outlines if node.has_key("/First"): subOutlines = [] - self.getOutlines(get(node["/First"]), subOutlines) + self.getOutlines(node["/First"], subOutlines) if subOutlines: outlines.append(subOutlines) if not node.has_key("/Next"): break - node = get(node["/Next"]) + node = node["/Next"] return outlines - def _buildDestination(self, array, title): - if not (isinstance(array, ArrayObject) and len(array) >= 2 and \ - isinstance(array[0], IndirectObject)): - return None - - pageKey = (array[0].generation, array[0].idnum) - if not self.pageNumbers.has_key(pageKey): - return None - - pageNum = self.pageNumbers[pageKey] - return Destination(*([title, pageNum]+array[1:])) + def _buildDestination(self, title, array): + page, typ = array[0:2] + array = array[2:] + return Destination(title, page, typ, *array) def _buildOutline(self, node): dest, title, outline = None, None, None if node.has_key("/A") and node.has_key("/Title"): # Action, section 8.5 (only type GoTo supported) - title = self.safeGetObject(node["/Title"]) - action = self.safeGetObject(node["/A"]) + title = node["/Title"] + action = node["/A"] if action["/S"] == "/GoTo": - dest = self.safeGetObject(action["/D"]) + dest = action["/D"] elif node.has_key("/Dest") and node.has_key("/Title"): # Destination, section 8.2.1 - title = self.safeGetObject(node["/Title"]) - dest = self.safeGetObject(node["/Dest"]) + title = node["/Title"] + dest = node["/Dest"] # if destination found, then create outline if dest: if isinstance(dest, ArrayObject): - outline = self._buildDestination(dest, title) - elif isinstance(dest, str) and self._namedDests.has_key(dest): + outline = self._buildDestination(title, dest) + elif isinstance(dest, unicode) and self._namedDests.has_key(dest): outline = self._namedDests[dest] - outline.title = title + outline[NameObject("/Title")] = title + else: + raise utils.PdfReadError("Unexpected destination %r" % dest) return outline ## @@ -478,7 +487,7 @@ class PdfFileReader(object): pages = property(lambda self: ConvertFunctionsToVirtualList(self.getNumPages, self.getPage), None, None) - def _flatten(self, pages = None, inherit = None): + def _flatten(self, pages=None, inherit=None): inheritablePageAttributes = ( NameObject("/Resources"), NameObject("/MediaBox"), NameObject("/CropBox"), NameObject("/Rotate") @@ -487,37 +496,25 @@ class PdfFileReader(object): inherit = dict() if pages == None: self.flattenedPages = [] - catalog = self.getObject(self.trailer["/Root"]) - pages = self.getObject(catalog["/Pages"]) - indirectReference = None - if isinstance(pages, IndirectObject): - indirectReference = pages - pages = self.getObject(pages) + catalog = self.trailer["/Root"].getObject() + pages = catalog["/Pages"].getObject() t = pages["/Type"] if t == "/Pages": for attr in inheritablePageAttributes: if pages.has_key(attr): inherit[attr] = pages[attr] - for page in self.safeGetObject(pages["/Kids"]): - self._flatten(page, inherit) + for page in pages["/Kids"]: + self._flatten(page.getObject(), inherit) elif t == "/Page": for attr,value in inherit.items(): # if the page has it's own value, it does not inherit the # parent's value: if not pages.has_key(attr): pages[attr] = value - pageObj = PageObject(self, indirectReference) + pageObj = PageObject(self) pageObj.update(pages) - if indirectReference: - key = (indirectReference.generation, indirectReference.idnum) - self.pageNumbers[key] = len(self.flattenedPages) self.flattenedPages.append(pageObj) - def safeGetObject(self, obj): - if isinstance(obj, IndirectObject): - return self.safeGetObject(self.getObject(obj)) - return obj - def getObject(self, indirectReference): retval = self.resolvedObjects.get(indirectReference.generation, {}).get(indirectReference.idnum, None) if retval != None: @@ -527,7 +524,7 @@ class PdfFileReader(object): # indirect reference to object in object stream # read the entire object stream into memory stmnum,idx = self.xref_objStm[indirectReference.idnum] - objStm = self.getObject(IndirectObject(stmnum, 0, self)) + objStm = IndirectObject(stmnum, 0, self).getObject() assert objStm['/Type'] == '/ObjStm' assert idx < objStm['/N'] streamData = StringIO(objStm.getData()) @@ -619,7 +616,7 @@ class PdfFileReader(object): # read all cross reference tables and their trailers self.xref = {} self.xref_objStm = {} - self.trailer = {} + self.trailer = DictionaryObject() while 1: # load the xref table stream.seek(startxref, 0) @@ -641,6 +638,16 @@ class PdfFileReader(object): cnt = 0 while cnt < size: line = stream.read(20) + # It's very clear in section 3.4.3 of the PDF spec + # that all cross-reference table lines are a fixed + # 20 bytes. However... some malformed PDF files + # use a single character EOL without a preceeding + # space. Detect that case, and seek the stream + # back one character. (0-9 means we've bled into + # the next xref entry, t means we've bled into the + # text "trailer"): + if line[-1] in "0123456789t": + stream.seek(-1, 1) offset, generation = line[:16].split(" ") offset, generation = int(offset), int(generation) if not self.xref.has_key(generation): @@ -669,8 +676,8 @@ class PdfFileReader(object): for key, value in newTrailer.items(): if not self.trailer.has_key(key): self.trailer[key] = value - if newTrailer.has_key(NameObject("/Prev")): - startxref = newTrailer[NameObject("/Prev")] + if newTrailer.has_key("/Prev"): + startxref = newTrailer["/Prev"] else: break elif x.isdigit(): @@ -681,43 +688,46 @@ class PdfFileReader(object): assert xrefstream["/Type"] == "/XRef" self.cacheIndirectObject(generation, idnum, xrefstream) streamData = StringIO(xrefstream.getData()) - num, size = xrefstream.get("/Index", [0, xrefstream.get("/Size")]) + idx_pairs = xrefstream.get("/Index", [0, xrefstream.get("/Size")]) entrySizes = xrefstream.get("/W") - cnt = 0 - while cnt < size: - for i in range(len(entrySizes)): - d = streamData.read(entrySizes[i]) - di = convertToInt(d, entrySizes[i]) - if i == 0: - xref_type = di - elif i == 1: - if xref_type == 0: - next_free_object = di - elif xref_type == 1: - byte_offset = di - elif xref_type == 2: - objstr_num = di - elif i == 2: - if xref_type == 0: - next_generation = di - elif xref_type == 1: - generation = di - elif xref_type == 2: - obstr_idx = di - if xref_type == 0: - pass - elif xref_type == 1: - if not self.xref.has_key(generation): - self.xref[generation] = {} - self.xref[generation][num] = byte_offset - elif xref_type == 2: - self.xref_objStm[num] = [objstr_num, obstr_idx] - cnt += 1 - num += 1 + for num, size in self._pairs(idx_pairs): + cnt = 0 + while cnt < size: + for i in range(len(entrySizes)): + d = streamData.read(entrySizes[i]) + di = convertToInt(d, entrySizes[i]) + if i == 0: + xref_type = di + elif i == 1: + if xref_type == 0: + next_free_object = di + elif xref_type == 1: + byte_offset = di + elif xref_type == 2: + objstr_num = di + elif i == 2: + if xref_type == 0: + next_generation = di + elif xref_type == 1: + generation = di + elif xref_type == 2: + obstr_idx = di + if xref_type == 0: + pass + elif xref_type == 1: + if not self.xref.has_key(generation): + self.xref[generation] = {} + if not num in self.xref[generation]: + self.xref[generation][num] = byte_offset + elif xref_type == 2: + if not num in self.xref_objStm: + self.xref_objStm[num] = [objstr_num, obstr_idx] + cnt += 1 + num += 1 trailerKeys = "/Root", "/Encrypt", "/Info", "/ID" for key in trailerKeys: if xrefstream.has_key(key) and not self.trailer.has_key(key): - self.trailer[NameObject(key)] = xrefstream[key] + self.trailer[NameObject(key)] = xrefstream.raw_get(key) if xrefstream.has_key("/Prev"): startxref = xrefstream["/Prev"] else: @@ -737,6 +747,14 @@ class PdfFileReader(object): assert False break + def _pairs(self, array): + i = 0 + while True: + yield array[i], array[i+1] + i += 2 + if (i+1) >= len(array): + break + def readNextEndLine(self, stream): line = "" while True: @@ -778,7 +796,7 @@ class PdfFileReader(object): self._override_encryption = False def _decrypt(self, password): - encrypt = self.safeGetObject(self.trailer['/Encrypt']) + encrypt = self.trailer['/Encrypt'].getObject() if encrypt['/Filter'] != '/Standard': raise NotImplementedError, "only Standard PDF encryption handler is available" if not (encrypt['/V'] in (1, 2)): @@ -788,13 +806,13 @@ class PdfFileReader(object): self._decryption_key = key return 1 else: - rev = self.safeGetObject(encrypt['/R']) + rev = encrypt['/R'].getObject() if rev == 2: keylen = 5 else: - keylen = self.safeGetObject(encrypt['/Length']) / 8 + keylen = encrypt['/Length'].getObject() / 8 key = _alg33_1(password, rev, keylen) - real_O = self.safeGetObject(encrypt["/O"]) + real_O = encrypt["/O"].getObject() if rev == 2: userpass = utils.RC4_encrypt(key, real_O) else: @@ -812,20 +830,20 @@ class PdfFileReader(object): return 0 def _authenticateUserPassword(self, password): - encrypt = self.safeGetObject(self.trailer['/Encrypt']) - rev = self.safeGetObject(encrypt['/R']) - owner_entry = self.safeGetObject(encrypt['/O']).original_bytes - p_entry = self.safeGetObject(encrypt['/P']) - id_entry = self.safeGetObject(self.trailer['/ID']) - id1_entry = self.safeGetObject(id_entry[0]) + encrypt = self.trailer['/Encrypt'].getObject() + rev = encrypt['/R'].getObject() + owner_entry = encrypt['/O'].getObject().original_bytes + p_entry = encrypt['/P'].getObject() + id_entry = self.trailer['/ID'].getObject() + id1_entry = id_entry[0].getObject() if rev == 2: U, key = _alg34(password, owner_entry, p_entry, id1_entry) elif rev >= 3: U, key = _alg35(password, rev, - self.safeGetObject(encrypt["/Length"]) / 8, owner_entry, + encrypt["/Length"].getObject() / 8, owner_entry, p_entry, id1_entry, - self.safeGetObject(encrypt.get("/EncryptMetadata", False))) - real_U = self.safeGetObject(encrypt['/U']).original_bytes + encrypt.get("/EncryptMetadata", BooleanObject(False)).getObject()) + real_U = encrypt['/U'].getObject().original_bytes return U == real_U, key def getIsEncrypted(self): @@ -874,10 +892,9 @@ def createRectangleAccessor(name, fallback): # will be created by accessing the {@link #PdfFileReader.getPage getPage} # function of the {@link #PdfFileReader PdfFileReader} class. class PageObject(DictionaryObject): - def __init__(self, pdf, indirectReference = None): + def __init__(self, pdf): DictionaryObject.__init__(self) self.pdf = pdf - self.indirectReference = indirectReference ## # Rotates a page clockwise by increments of 90 degrees. @@ -1058,7 +1075,7 @@ class PageObject(DictionaryObject): # implementation-defined manner. Default value: same as MediaBox. #

            # Stability: Added in v1.4, will exist for all future v1.x releases. - cropBox = createRectangleAccessor("/CropBox", ("/CropBox",)) + cropBox = createRectangleAccessor("/CropBox", ("/MediaBox",)) ## # A rectangle (RectangleObject), expressed in default user space units, @@ -1110,7 +1127,15 @@ class ContentStream(DecodedStreamObject): break stream.seek(-1, 1) if peek.isalpha() or peek == "'" or peek == '"': - operator = readUntilWhitespace(stream, maxchars=2) + operator = "" + while True: + tok = stream.read(1) + if tok.isspace() or tok in NameObject.delimiterCharacters: + stream.seek(-1, 1) + break + elif tok == '': + break + operator += tok if operator == "BI": # begin inline image - a completely different parsing # mechanism is required, of course... thanks buddy... @@ -1120,6 +1145,14 @@ class ContentStream(DecodedStreamObject): else: self.operations.append((operands, operator)) operands = [] + elif peek == '%': + # If we encounter a comment in the content stream, we have to + # handle it here. Typically, readObject will handle + # encountering a comment -- but readObject assumes that + # following the comment must be the object we're trying to + # read. In this case, it could be an operator instead. + while peek not in ('\r', '\n'): + peek = stream.read(1) else: operands.append(readObject(stream, None)) @@ -1251,86 +1284,74 @@ class DocumentInformation(DictionaryObject): # See section 8.2.1 of the PDF 1.6 reference. # Stability: Added in v1.10, will exist for all v1.x releases. class Destination(DictionaryObject): - def __init__(self, *args): + def __init__(self, title, page, typ, *args): DictionaryObject.__init__(self) - self.title = args[0] - self["/Page"], self["/Type"] = args[1], args[2] + self[NameObject("/Title")] = title + self[NameObject("/Page")] = page + self[NameObject("/Type")] = typ # from table 8.2 of the PDF 1.6 reference. - mapNull = lambda x: {True: None, False: x}[isinstance(x, NullObject)] - params = map(mapNull, args[3:]) - type = self["/Type"] - - if type == "/XYZ": - self["/Left"], self["/Top"], self["/Zoom"] = params - elif type == "/FitR": - self["/Left"], self["/Bottom"], \ - self["/Right"], self["/Top"] = params - elif type in ["/FitH", "FitBH"]: - self["/Top"], = params - elif type in ["/FitV", "FitBV"]: - self["/Left"], = params - elif type in ["/Fit", "FitB"]: + if typ == "/XYZ": + (self[NameObject("/Left")], self[NameObject("/Top")], + self[NameObject("/Zoom")]) = args + elif typ == "/FitR": + (self[NameObject("/Left")], self[NameObject("/Bottom")], + self[NameObject("/Right")], self[NameObject("/Top")]) = args + elif typ in ["/FitH", "FitBH"]: + self[NameObject("/Top")], = args + elif typ in ["/FitV", "FitBV"]: + self[NameObject("/Left")], = args + elif typ in ["/Fit", "FitB"]: pass else: - raise utils.PdfReadError, "Unknown Destination Type: " + type + raise utils.PdfReadError("Unknown Destination Type: %r" % typ) - def setTitle(self, title): - self["/Title"] = title.strip() - ## - # Read-write property accessing the destination title. + # Read-only property accessing the destination title. # @return A string. - title = property(lambda self: self.get("/Title"), setTitle, None) + title = property(lambda self: self.get("/Title")) ## # Read-only property accessing the destination page. # @return An integer. - page = property(lambda self: self.get("/Page"), None, None) + page = property(lambda self: self.get("/Page")) ## # Read-only property accessing the destination type. # @return A string. - type = property(lambda self: self.get("/Type"), None, None) + typ = property(lambda self: self.get("/Type")) ## # Read-only property accessing the zoom factor. # @return A number, or None if not available. - zoom = property(lambda self: self.get("/Zoom", None), None, None) + zoom = property(lambda self: self.get("/Zoom", None)) ## # Read-only property accessing the left horizontal coordinate. # @return A number, or None if not available. - left = property(lambda self: self.get("/Left", None), None, None) + left = property(lambda self: self.get("/Left", None)) ## # Read-only property accessing the right horizontal coordinate. # @return A number, or None if not available. - right = property(lambda self: self.get("/Right", None), None, None) + right = property(lambda self: self.get("/Right", None)) ## # Read-only property accessing the top vertical coordinate. # @return A number, or None if not available. - top = property(lambda self: self.get("/Top", None), None, None) + top = property(lambda self: self.get("/Top", None)) ## # Read-only property accessing the bottom vertical coordinate. # @return A number, or None if not available. - bottom = property(lambda self: self.get("/Bottom", None), None, None) - + bottom = property(lambda self: self.get("/Bottom", None)) def convertToInt(d, size): - if size <= 4: - d = "\x00\x00\x00\x00" + d - d = d[-4:] - return struct.unpack(">l", d)[0] - elif size <= 8: - d = "\x00\x00\x00\x00\x00\x00\x00\x00" + d - d = d[-8:] - return struct.unpack(">q", d)[0] - else: - # size too big - assert False + if size > 8: + raise utils.PdfReadError("invalid size in convertToInt") + d = "\x00\x00\x00\x00\x00\x00\x00\x00" + d + d = d[-8:] + return struct.unpack(">q", d)[0] # ref: pdf1.8 spec section 3.5.2 algorithm 3.2 _encryption_padding = '\x28\xbf\x4e\x5e\x4e\x75\x8a\x41\x64\x00\x4e\x56' + \ diff --git a/src/calibre/ebooks/pyPdf/utils.py b/src/pyPdf/utils.py similarity index 90% rename from src/calibre/ebooks/pyPdf/utils.py rename to src/pyPdf/utils.py index 860a42e669..dd0a3d002a 100644 --- a/src/calibre/ebooks/pyPdf/utils.py +++ b/src/pyPdf/utils.py @@ -34,6 +34,19 @@ Utility functions for PDF library. __author__ = "Mathieu Fenniak" __author_email__ = "biziqe@mathieu.fenniak.net" +#ENABLE_PSYCO = False +#if ENABLE_PSYCO: +# try: +# import psyco +# except ImportError: +# ENABLE_PSYCO = False +# +#if not ENABLE_PSYCO: +# class psyco: +# def proxy(func): +# return func +# proxy = staticmethod(proxy) + def readUntilWhitespace(stream, maxchars=None): txt = "" while True: diff --git a/src/pyPdf/xmp.py b/src/pyPdf/xmp.py new file mode 100644 index 0000000000..b070df9093 --- /dev/null +++ b/src/pyPdf/xmp.py @@ -0,0 +1,355 @@ +import re +import datetime +import decimal +from generic import PdfObject +from xml.dom import getDOMImplementation +from xml.dom.minidom import parseString + +RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +DC_NAMESPACE = "http://purl.org/dc/elements/1.1/" +XMP_NAMESPACE = "http://ns.adobe.com/xap/1.0/" +PDF_NAMESPACE = "http://ns.adobe.com/pdf/1.3/" +XMPMM_NAMESPACE = "http://ns.adobe.com/xap/1.0/mm/" + +# What is the PDFX namespace, you might ask? I might ask that too. It's +# a completely undocumented namespace used to place "custom metadata" +# properties, which are arbitrary metadata properties with no semantic or +# documented meaning. Elements in the namespace are key/value-style storage, +# where the element name is the key and the content is the value. The keys +# are transformed into valid XML identifiers by substituting an invalid +# identifier character with \u2182 followed by the unicode hex ID of the +# original character. A key like "my car" is therefore "my\u21820020car". +# +# \u2182, in case you're wondering, is the unicode character +# \u{ROMAN NUMERAL TEN THOUSAND}, a straightforward and obvious choice for +# escaping characters. +# +# Intentional users of the pdfx namespace should be shot on sight. A +# custom data schema and sensical XML elements could be used instead, as is +# suggested by Adobe's own documentation on XMP (under "Extensibility of +# Schemas"). +# +# Information presented here on the /pdfx/ schema is a result of limited +# reverse engineering, and does not constitute a full specification. +PDFX_NAMESPACE = "http://ns.adobe.com/pdfx/1.3/" + +iso8601 = re.compile(""" + (?P[0-9]{4}) + (- + (?P[0-9]{2}) + (- + (?P[0-9]+) + (T + (?P[0-9]{2}): + (?P[0-9]{2}) + (:(?P[0-9]{2}(.[0-9]+)?))? + (?PZ|[-+][0-9]{2}:[0-9]{2}) + )? + )? + )? + """, re.VERBOSE) + +## +# An object that represents Adobe XMP metadata. +class XmpInformation(PdfObject): + + def __init__(self, stream): + self.stream = stream + docRoot = parseString(self.stream.getData()) + self.rdfRoot = docRoot.getElementsByTagNameNS(RDF_NAMESPACE, "RDF")[0] + self.cache = {} + + def writeToStream(self, stream, encryption_key): + self.stream.writeToStream(stream, encryption_key) + + def getElement(self, aboutUri, namespace, name): + for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"): + if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri: + attr = desc.getAttributeNodeNS(namespace, name) + if attr != None: + yield attr + for element in desc.getElementsByTagNameNS(namespace, name): + yield element + + def getNodesInNamespace(self, aboutUri, namespace): + for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"): + if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri: + for i in range(desc.attributes.length): + attr = desc.attributes.item(i) + if attr.namespaceURI == namespace: + yield attr + for child in desc.childNodes: + if child.namespaceURI == namespace: + yield child + + def _getText(self, element): + text = "" + for child in element.childNodes: + if child.nodeType == child.TEXT_NODE: + text += child.data + return text + + def _converter_string(value): + return value + + def _converter_date(value): + m = iso8601.match(value) + year = int(m.group("year")) + month = int(m.group("month") or "1") + day = int(m.group("day") or "1") + hour = int(m.group("hour") or "0") + minute = int(m.group("minute") or "0") + second = decimal.Decimal(m.group("second") or "0") + seconds = second.to_integral(decimal.ROUND_FLOOR) + milliseconds = (second - seconds) * 1000000 + tzd = m.group("tzd") or "Z" + dt = datetime.datetime(year, month, day, hour, minute, seconds, milliseconds) + if tzd != "Z": + tzd_hours, tzd_minutes = [int(x) for x in tzd.split(":")] + tzd_hours *= -1 + if tzd_hours < 0: + tzd_minutes *= -1 + dt = dt + datetime.timedelta(hours=tzd_hours, minutes=tzd_minutes) + return dt + _test_converter_date = staticmethod(_converter_date) + + def _getter_bag(namespace, name, converter): + def get(self): + cached = self.cache.get(namespace, {}).get(name) + if cached: + return cached + retval = [] + for element in self.getElement("", namespace, name): + bags = element.getElementsByTagNameNS(RDF_NAMESPACE, "Bag") + if len(bags): + for bag in bags: + for item in bag.getElementsByTagNameNS(RDF_NAMESPACE, "li"): + value = self._getText(item) + value = converter(value) + retval.append(value) + ns_cache = self.cache.setdefault(namespace, {}) + ns_cache[name] = retval + return retval + return get + + def _getter_seq(namespace, name, converter): + def get(self): + cached = self.cache.get(namespace, {}).get(name) + if cached: + return cached + retval = [] + for element in self.getElement("", namespace, name): + seqs = element.getElementsByTagNameNS(RDF_NAMESPACE, "Seq") + if len(seqs): + for seq in seqs: + for item in seq.getElementsByTagNameNS(RDF_NAMESPACE, "li"): + value = self._getText(item) + value = converter(value) + retval.append(value) + else: + value = converter(self._getText(element)) + retval.append(value) + ns_cache = self.cache.setdefault(namespace, {}) + ns_cache[name] = retval + return retval + return get + + def _getter_langalt(namespace, name, converter): + def get(self): + cached = self.cache.get(namespace, {}).get(name) + if cached: + return cached + retval = {} + for element in self.getElement("", namespace, name): + alts = element.getElementsByTagNameNS(RDF_NAMESPACE, "Alt") + if len(alts): + for alt in alts: + for item in alt.getElementsByTagNameNS(RDF_NAMESPACE, "li"): + value = self._getText(item) + value = converter(value) + retval[item.getAttribute("xml:lang")] = value + else: + retval["x-default"] = converter(self._getText(element)) + ns_cache = self.cache.setdefault(namespace, {}) + ns_cache[name] = retval + return retval + return get + + def _getter_single(namespace, name, converter): + def get(self): + cached = self.cache.get(namespace, {}).get(name) + if cached: + return cached + value = None + for element in self.getElement("", namespace, name): + if element.nodeType == element.ATTRIBUTE_NODE: + value = element.nodeValue + else: + value = self._getText(element) + break + if value != None: + value = converter(value) + ns_cache = self.cache.setdefault(namespace, {}) + ns_cache[name] = value + return value + return get + + ## + # Contributors to the resource (other than the authors). An unsorted + # array of names. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_contributor = property(_getter_bag(DC_NAMESPACE, "contributor", _converter_string)) + + ## + # Text describing the extent or scope of the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_coverage = property(_getter_single(DC_NAMESPACE, "coverage", _converter_string)) + + ## + # A sorted array of names of the authors of the resource, listed in order + # of precedence. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_creator = property(_getter_seq(DC_NAMESPACE, "creator", _converter_string)) + + ## + # A sorted array of dates (datetime.datetime instances) of signifigance to + # the resource. The dates and times are in UTC. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_date = property(_getter_seq(DC_NAMESPACE, "date", _converter_date)) + + ## + # A language-keyed dictionary of textual descriptions of the content of the + # resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_description = property(_getter_langalt(DC_NAMESPACE, "description", _converter_string)) + + ## + # The mime-type of the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_format = property(_getter_single(DC_NAMESPACE, "format", _converter_string)) + + ## + # Unique identifier of the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_identifier = property(_getter_single(DC_NAMESPACE, "identifier", _converter_string)) + + ## + # An unordered array specifying the languages used in the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_language = property(_getter_bag(DC_NAMESPACE, "language", _converter_string)) + + ## + # An unordered array of publisher names. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_publisher = property(_getter_bag(DC_NAMESPACE, "publisher", _converter_string)) + + ## + # An unordered array of text descriptions of relationships to other + # documents. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_relation = property(_getter_bag(DC_NAMESPACE, "relation", _converter_string)) + + ## + # A language-keyed dictionary of textual descriptions of the rights the + # user has to this resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_rights = property(_getter_langalt(DC_NAMESPACE, "rights", _converter_string)) + + ## + # Unique identifier of the work from which this resource was derived. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_source = property(_getter_single(DC_NAMESPACE, "source", _converter_string)) + + ## + # An unordered array of descriptive phrases or keywrods that specify the + # topic of the content of the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_subject = property(_getter_bag(DC_NAMESPACE, "subject", _converter_string)) + + ## + # A language-keyed dictionary of the title of the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_title = property(_getter_langalt(DC_NAMESPACE, "title", _converter_string)) + + ## + # An unordered array of textual descriptions of the document type. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + dc_type = property(_getter_bag(DC_NAMESPACE, "type", _converter_string)) + + ## + # An unformatted text string representing document keywords. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + pdf_keywords = property(_getter_single(PDF_NAMESPACE, "Keywords", _converter_string)) + + ## + # The PDF file version, for example 1.0, 1.3. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + pdf_pdfversion = property(_getter_single(PDF_NAMESPACE, "PDFVersion", _converter_string)) + + ## + # The name of the tool that created the PDF document. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + pdf_producer = property(_getter_single(PDF_NAMESPACE, "Producer", _converter_string)) + + ## + # The date and time the resource was originally created. The date and + # time are returned as a UTC datetime.datetime object. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmp_createDate = property(_getter_single(XMP_NAMESPACE, "CreateDate", _converter_date)) + + ## + # The date and time the resource was last modified. The date and time + # are returned as a UTC datetime.datetime object. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmp_modifyDate = property(_getter_single(XMP_NAMESPACE, "ModifyDate", _converter_date)) + + ## + # The date and time that any metadata for this resource was last + # changed. The date and time are returned as a UTC datetime.datetime + # object. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmp_metadataDate = property(_getter_single(XMP_NAMESPACE, "MetadataDate", _converter_date)) + + ## + # The name of the first known tool used to create the resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmp_creatorTool = property(_getter_single(XMP_NAMESPACE, "CreatorTool", _converter_string)) + + ## + # The common identifier for all versions and renditions of this resource. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmpmm_documentId = property(_getter_single(XMPMM_NAMESPACE, "DocumentID", _converter_string)) + + ## + # An identifier for a specific incarnation of a document, updated each + # time a file is saved. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + xmpmm_instanceId = property(_getter_single(XMPMM_NAMESPACE, "InstanceID", _converter_string)) + + def custom_properties(self): + if not hasattr(self, "_custom_properties"): + self._custom_properties = {} + for node in self.getNodesInNamespace("", PDFX_NAMESPACE): + key = node.localName + while True: + # see documentation about PDFX_NAMESPACE earlier in file + idx = key.find(u"\u2182") + if idx == -1: + break + key = key[:idx] + chr(int(key[idx+1:idx+5], base=16)) + key[idx+5:] + if node.nodeType == node.ATTRIBUTE_NODE: + value = node.nodeValue + else: + value = self._getText(node) + self._custom_properties[key] = value + return self._custom_properties + + ## + # Retrieves custom metadata properties defined in the undocumented pdfx + # metadata schema. + #

            Stability: Added in v1.12, will exist for all future v1.x releases. + # @return Returns a dictionary of key/value items for custom metadata + # properties. + custom_properties = property(custom_properties) + + diff --git a/upload.py b/upload.py index e528c6f257..5709e42023 100644 --- a/upload.py +++ b/upload.py @@ -27,11 +27,12 @@ TXT2LRF = "src/calibre/ebooks/lrf/txt/demo" MOBILEREAD = 'ftp://dev.mobileread.com/calibre/' BUILD_SCRIPT ='''\ #!/bin/bash +export CALIBRE_BUILDBOT=1 cd ~/build && \ rsync -avz --exclude src/calibre/plugins --exclude calibre/src/calibre.egg-info --exclude docs --exclude .bzr --exclude .build --exclude build --exclude dist --exclude "*.pyc" --exclude "*.pyo" rsync://%(host)s/work/%(project)s . && \ cd %(project)s && \ %%s && \ -rm -rf build/* && \ +rm -rf build/* dist/* && \ %%s %%s '''%dict(host=HOST, project=PROJECT) check_call = partial(_check_call, shell=True) @@ -101,7 +102,7 @@ def build_osx(shutdown=True): def build_linux(shutdown=True): installer = installer_name('tar.bz2') vm = '/vmware/linux/libprs500-gentoo.vmx' - start_vm(vm, 'linux', (BUILD_SCRIPT%('sudo python setup.py develop', 'python','installer/linux/freeze.py')).replace('rm ', 'sudo rm ')) + start_vm(vm, 'linux', (BUILD_SCRIPT%('sudo python setup.py develop', 'python','installer/linux/freeze.py')).replace('rm ', 'sudo rm '), sleep=100) subprocess.check_call(('scp', 'linux:/tmp/%s'%os.path.basename(installer), 'dist')) if not os.path.exists(installer): raise Exception('Failed to build installer '+installer) @@ -202,14 +203,14 @@ def upload_docs(): def upload_user_manual(): check_call('python setup.py manual') - check_call('scp -r .build/html/* divok:%s'%USER_MANUAL) + check_call('scp -r src/calibre/manual/.build/html/* divok:%s'%USER_MANUAL) def build_src_tarball(): - check_call('bzr export dist/calibre-%s.tar.bz2'%__version__) + check_call('bzr export dist/calibre-%s.tar.gz'%__version__) def upload_src_tarball(): - check_call('ssh divok rm -f %s/calibre-\*.tar.bz2'%DOWNLOADS) - check_call('scp dist/calibre-*.tar.bz2 divok:%s/'%DOWNLOADS) + check_call('ssh divok rm -f %s/calibre-\*.tar.gz'%DOWNLOADS) + check_call('scp dist/calibre-*.tar.gz divok:%s/'%DOWNLOADS) def stage_one(): check_call('sudo rm -rf build', shell=True) @@ -218,26 +219,34 @@ def stage_one(): os.mkdir('docs') check_call('python setup.py build', shell=True) check_call('sudo python setup.py develop', shell=True) - check_call('make', shell=True) tag_release() upload_demo() def stage_two(): subprocess.check_call('rm -rf dist/*', shell=True) build_installers() - build_src_tarball() def stage_three(): print 'Uploading installers...' upload_installers() - print 'Uploading to PyPI' - upload_src_tarball() + print 'Uploading documentation...' upload_docs() upload_user_manual() - check_call('python setup.py register bdist_egg --exclude-source-files upload') + print 'Uploading to PyPI...' + check_call('rm -f dist/*') + check_call('python setup.py register') + check_call('python setup.py bdist_egg --exclude-source-files upload') + check_call('python setup.py sdist upload') + upload_src_tarball() check_call('''rm -rf dist/* build/*''') check_call('''ssh divok bzr update /var/www/calibre.kovidgoyal.net/calibre/''') +def betas(): + subprocess.check_call('rm -f dist/*', shell=True) + build_installers() + check_call('ssh divok rm -f /var/www/calibre.kovidgoyal.net/htdocs/downloads/betas/*') + check_call('scp dist/* divok:/var/www/calibre.kovidgoyal.net/htdocs/downloads/betas/') + def main(args=sys.argv): print 'Starting stage one...' stage_one()