mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-11 09:13:57 -04:00
convert some legacy percent format (auto-fix)
ruff 'UP031'
This commit is contained in:
parent
534293eabc
commit
0560b429bf
@ -26,7 +26,7 @@ def clone_node(node, parent):
|
||||
def merge():
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
ans = etree.fromstring(
|
||||
'<svg xmlns="%s" xmlns:xlink="%s"/>' % (SVG_NS, XLINK_NS),
|
||||
'<svg xmlns="{}" xmlns:xlink="{}"/>'.format(SVG_NS, XLINK_NS),
|
||||
parser=etree.XMLParser(
|
||||
recover=True, no_network=True, resolve_entities=False
|
||||
)
|
||||
@ -42,7 +42,7 @@ def merge():
|
||||
recover=True, no_network=True, resolve_entities=False
|
||||
)
|
||||
)
|
||||
symbol = ans.makeelement('{%s}symbol' % SVG_NS)
|
||||
symbol = ans.makeelement('{{{}}}symbol'.format(SVG_NS))
|
||||
symbol.set('viewBox', svg.get('viewBox'))
|
||||
symbol.set('id', 'icon-' + f.rpartition('.')[0])
|
||||
for child in svg.iterchildren('*'):
|
||||
|
@ -97,7 +97,7 @@ today_fmt = '%B %d, %Y'
|
||||
unused_docs = ['global', 'cli/global']
|
||||
|
||||
locale_dirs = ['locale/']
|
||||
title = '%s User Manual' % __appname__
|
||||
title = '{} User Manual'.format(__appname__)
|
||||
needs_localization = language not in {'en', 'eng'}
|
||||
if needs_localization:
|
||||
import gettext
|
||||
@ -253,5 +253,5 @@ latex_show_pagerefs = True
|
||||
latex_show_urls = 'footnote'
|
||||
latex_elements = {
|
||||
'papersize':'letterpaper',
|
||||
'preamble': r'\renewcommand{\pageautorefname}{%s}' % _('page'),
|
||||
'preamble': r'\renewcommand{{\pageautorefname}}{{{}}}'.format(_('page')),
|
||||
}
|
||||
|
@ -195,13 +195,13 @@ details and examples.
|
||||
lines = []
|
||||
for cmd in COMMANDS:
|
||||
parser = option_parser_for(cmd)()
|
||||
lines += ['.. _calibredb-%s-%s:' % (language, cmd), '']
|
||||
lines += ['.. _calibredb-{}-{}:'.format(language, cmd), '']
|
||||
lines += [cmd, '~'*20, '']
|
||||
usage = parser.usage.strip()
|
||||
usage = [i for i in usage.replace('%prog', 'calibredb').splitlines()]
|
||||
cmdline = ' '+usage[0]
|
||||
usage = usage[1:]
|
||||
usage = [re.sub(r'(%s)([^a-zA-Z0-9])'%cmd, r':command:`\1`\2', i) for i in usage]
|
||||
usage = [re.sub(r'({})([^a-zA-Z0-9])'.format(cmd), r':command:`\1`\2', i) for i in usage]
|
||||
lines += ['.. code-block:: none', '', cmdline, '']
|
||||
lines += usage
|
||||
groups = [(None, None, parser.option_list)]
|
||||
@ -257,7 +257,7 @@ def generate_ebook_convert_help(preamble, app):
|
||||
def update_cli_doc(name, raw, language):
|
||||
if isinstance(raw, bytes):
|
||||
raw = raw.decode('utf-8')
|
||||
path = 'generated/%s/%s.rst' % (language, name)
|
||||
path = 'generated/{}/{}.rst'.format(language, name)
|
||||
old_raw = open(path, encoding='utf-8').read() if os.path.exists(path) else ''
|
||||
if not os.path.exists(path) or old_raw != raw:
|
||||
import difflib
|
||||
@ -352,7 +352,7 @@ def cli_docs(language):
|
||||
usage = [mark_options(i) for i in parser.usage.replace('%prog', cmd).splitlines()]
|
||||
cmdline = usage[0]
|
||||
usage = usage[1:]
|
||||
usage = [i.replace(cmd, ':command:`%s`'%cmd) for i in usage]
|
||||
usage = [i.replace(cmd, ':command:`{}`'.format(cmd)) for i in usage]
|
||||
usage = '\n'.join(usage)
|
||||
preamble = CLI_PREAMBLE.format(cmd=cmd, cmdref=cmd + '-' + language, cmdline=cmdline, usage=usage)
|
||||
if cmd == 'ebook-convert':
|
||||
@ -382,7 +382,7 @@ def template_docs(language):
|
||||
|
||||
def localized_path(app, langcode, pagename):
|
||||
href = app.builder.get_target_uri(pagename)
|
||||
href = re.sub(r'generated/[a-z]+/', 'generated/%s/' % langcode, href)
|
||||
href = re.sub(r'generated/[a-z]+/', 'generated/{}/'.format(langcode), href)
|
||||
prefix = '/'
|
||||
if langcode != 'en':
|
||||
prefix += langcode + '/'
|
||||
@ -405,7 +405,7 @@ def setup_man_pages(app):
|
||||
documented_cmds = get_cli_docs()[0]
|
||||
man_pages = []
|
||||
for cmd, option_parser in documented_cmds:
|
||||
path = 'generated/%s/%s' % (app.config.language, cmd)
|
||||
path = 'generated/{}/{}'.format(app.config.language, cmd)
|
||||
man_pages.append((
|
||||
path, cmd, cmd, 'Kovid Goyal', 1
|
||||
))
|
||||
|
@ -49,7 +49,7 @@ class EPUBHelpBuilder(EpubBuilder):
|
||||
imgname = container.href_to_name(img.get('src'), name)
|
||||
fmt, width, height = identify(container.raw_data(imgname))
|
||||
if width == -1:
|
||||
raise ValueError('Failed to read size of: %s' % imgname)
|
||||
raise ValueError('Failed to read size of: {}'.format(imgname))
|
||||
img.set('style', 'width: %dpx; height: %dpx' % (width, height))
|
||||
|
||||
def fix_opf(self, container):
|
||||
|
@ -17,12 +17,13 @@ exclude = [
|
||||
quote-style = 'single'
|
||||
|
||||
[lint]
|
||||
ignore = ['E402', 'E722', 'E741', 'UP012', 'UP030', 'UP031', 'UP032', 'UP038']
|
||||
ignore = ['E402', 'E722', 'E741', 'UP012', 'UP030', 'UP032', 'UP038']
|
||||
select = ['E', 'F', 'I', 'W', 'INT', 'Q', 'UP']
|
||||
|
||||
[lint.per-file-ignores]
|
||||
"recipes/*" = ['UP']
|
||||
"manual/plugin_examples/*" = ['UP']
|
||||
"src/calibre/*" = ['UP031']
|
||||
"src/calibre/ebooks/unihandecode/*codepoints.py" = ['E501']
|
||||
"src/calibre/ebooks/metadata/sources/*" = ['UP']
|
||||
"src/calibre/gui2/store/stores/*" = ['UP']
|
||||
|
@ -126,7 +126,7 @@ def initialize_constants():
|
||||
with open(os.path.join(SRC, 'calibre/constants.py'), 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
nv = re.search(r'numeric_version\s+=\s+\((\d+), (\d+), (\d+)\)', src)
|
||||
__version__ = '%s.%s.%s'%(nv.group(1), nv.group(2), nv.group(3))
|
||||
__version__ = '{}.{}.{}'.format(nv.group(1), nv.group(2), nv.group(3))
|
||||
__appname__ = re.search(r'__appname__\s+=\s+(u{0,1})[\'"]([^\'"]+)[\'"]',
|
||||
src).group(2)
|
||||
with open(os.path.join(SRC, 'calibre/linux.py'), 'rb') as sf:
|
||||
|
@ -83,7 +83,7 @@ def lazy_load(name):
|
||||
try:
|
||||
return getattr(build_environment, name)
|
||||
except AttributeError:
|
||||
raise ImportError('The setup.build_environment module has no symbol named: %s' % name)
|
||||
raise ImportError('The setup.build_environment module has no symbol named: {}'.format(name))
|
||||
|
||||
|
||||
def expand_file_list(items, is_paths=True, cross_compile_for='native'):
|
||||
@ -617,8 +617,8 @@ class Build(Command):
|
||||
try:
|
||||
subprocess.check_call(*args, **kwargs)
|
||||
except:
|
||||
cmdline = ' '.join(['"%s"' % (arg) if ' ' in arg else arg for arg in args[0]])
|
||||
print('Error while executing: %s\n' % (cmdline))
|
||||
cmdline = ' '.join(['"{}"'.format(arg) if ' ' in arg else arg for arg in args[0]])
|
||||
print('Error while executing: {}\n'.format(cmdline))
|
||||
raise
|
||||
|
||||
def build_headless(self):
|
||||
|
@ -113,7 +113,7 @@ qraw = subprocess.check_output([QMAKE, '-query']).decode('utf-8')
|
||||
|
||||
|
||||
def readvar(name):
|
||||
return re.search('^%s:(.+)$' % name, qraw, flags=re.M).group(1).strip()
|
||||
return re.search('^{}:(.+)$'.format(name), qraw, flags=re.M).group(1).strip()
|
||||
|
||||
|
||||
qt = {x:readvar(y) for x, y in {'libs':'QT_INSTALL_LIBS', 'plugins':'QT_INSTALL_PLUGINS'}.items()}
|
||||
|
@ -56,11 +56,11 @@ class Bug:
|
||||
if int(bug) > 100000 and action != 'See':
|
||||
self.close_bug(bug, action)
|
||||
return match.group() + f' [{summary}]({LAUNCHPAD_BUG % bug})'
|
||||
return match.group() + ' (%s)' % summary
|
||||
return match.group() + ' ({})'.format(summary)
|
||||
return match.group()
|
||||
|
||||
def close_bug(self, bug, action):
|
||||
print('Closing bug #%s' % bug)
|
||||
print('Closing bug #{}'.format(bug))
|
||||
suffix = (
|
||||
'The fix will be in the next release. '
|
||||
'calibre is usually released every alternate Friday.'
|
||||
|
@ -24,7 +24,7 @@ class GitVersion(Command):
|
||||
nv = nv.replace('-', '.')
|
||||
except subprocess.CalledProcessError:
|
||||
raise SystemExit('Error: not a git checkout')
|
||||
newsrc = re.sub(r'(git_version = ).*', r'\1%s' % repr(nv), src)
|
||||
newsrc = re.sub(r'(git_version = ).*', r'\1{}'.format(repr(nv)), src)
|
||||
self.info('new version is:', nv)
|
||||
|
||||
with open(constants_file, 'wb') as f:
|
||||
|
@ -61,8 +61,8 @@ class GUI(Command):
|
||||
if self.newer(self.QRC, sources):
|
||||
self.info('Creating images.qrc')
|
||||
for s in sources:
|
||||
files.append('<file>%s</file>'%s)
|
||||
manifest = '<RCC>\n<qresource prefix="/">\n%s\n</qresource>\n</RCC>'%'\n'.join(sorted(files))
|
||||
files.append('<file>{}</file>'.format(s))
|
||||
manifest = '<RCC>\n<qresource prefix="/">\n{}\n</qresource>\n</RCC>'.format('\n'.join(sorted(files)))
|
||||
if not isinstance(manifest, bytes):
|
||||
manifest = manifest.encode('utf-8')
|
||||
with open('images.qrc', 'wb') as f:
|
||||
|
@ -116,8 +116,7 @@ class SourceForge(Base): # {{{
|
||||
try:
|
||||
check_call([
|
||||
'rsync', '-h', '-zz', '--progress', '-e', 'ssh -x', x,
|
||||
'%s,%s@frs.sourceforge.net:%s' %
|
||||
(self.username, self.project, self.rdir + '/')
|
||||
'{},{}@frs.sourceforge.net:{}'.format(self.username, self.project, self.rdir + '/')
|
||||
])
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit(1)
|
||||
@ -160,15 +159,14 @@ class GitHub(Base): # {{{
|
||||
fname = os.path.basename(path)
|
||||
if fname in existing_assets:
|
||||
self.info(
|
||||
'Deleting %s from GitHub with id: %s' %
|
||||
(fname, existing_assets[fname])
|
||||
'Deleting {} from GitHub with id: {}'.format(fname, existing_assets[fname])
|
||||
)
|
||||
r = self.requests.delete(url.format(existing_assets[fname]))
|
||||
if r.status_code != 204:
|
||||
self.fail(r, 'Failed to delete %s from GitHub' % fname)
|
||||
self.fail(r, 'Failed to delete {} from GitHub'.format(fname))
|
||||
r = self.do_upload(upload_url, path, desc, fname)
|
||||
if r.status_code != 201:
|
||||
self.fail(r, 'Failed to upload file: %s' % fname)
|
||||
self.fail(r, 'Failed to upload file: {}'.format(fname))
|
||||
try:
|
||||
r = self.requests.patch(
|
||||
url.format(r.json()['id']),
|
||||
@ -187,25 +185,22 @@ class GitHub(Base): # {{{
|
||||
})
|
||||
)
|
||||
if r.status_code != 200:
|
||||
self.fail(r, 'Failed to set label for %s' % fname)
|
||||
self.fail(r, 'Failed to set label for {}'.format(fname))
|
||||
|
||||
def clean_older_releases(self, releases):
|
||||
for release in releases:
|
||||
if release.get('assets',
|
||||
None) and release['tag_name'] != self.current_tag_name:
|
||||
self.info(
|
||||
'\nDeleting old released installers from: %s' %
|
||||
release['tag_name']
|
||||
'\nDeleting old released installers from: {}'.format(release['tag_name'])
|
||||
)
|
||||
for asset in release['assets']:
|
||||
r = self.requests.delete(
|
||||
self.API + 'repos/%s/%s/releases/assets/%s' %
|
||||
(self.username, self.reponame, asset['id'])
|
||||
self.API + 'repos/{}/{}/releases/assets/{}'.format(self.username, self.reponame, asset['id'])
|
||||
)
|
||||
if r.status_code != 204:
|
||||
self.fail(
|
||||
r, 'Failed to delete obsolete asset: %s for release: %s'
|
||||
% (asset['name'], release['tag_name'])
|
||||
r, 'Failed to delete obsolete asset: {} for release: {}'.format(asset['name'], release['tag_name'])
|
||||
)
|
||||
|
||||
def do_upload(self, url, path, desc, fname):
|
||||
@ -223,7 +218,7 @@ class GitHub(Base): # {{{
|
||||
)
|
||||
|
||||
def fail(self, r, msg):
|
||||
print(msg, ' Status Code: %s' % r.status_code, file=sys.stderr)
|
||||
print(msg, ' Status Code: {}'.format(r.status_code), file=sys.stderr)
|
||||
print('JSON from response:', file=sys.stderr)
|
||||
pprint(dict(r.json()), stream=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
@ -260,14 +255,14 @@ class GitHub(Base): # {{{
|
||||
data=json.dumps({
|
||||
'tag_name': self.current_tag_name,
|
||||
'target_commitish': 'master',
|
||||
'name': 'version %s' % self.version,
|
||||
'body': 'Release version %s' % self.version,
|
||||
'name': 'version {}'.format(self.version),
|
||||
'body': 'Release version {}'.format(self.version),
|
||||
'draft': False,
|
||||
'prerelease': False
|
||||
})
|
||||
)
|
||||
if r.status_code != 201:
|
||||
self.fail(r, 'Failed to create release for version: %s' % self.version)
|
||||
self.fail(r, 'Failed to create release for version: {}'.format(self.version))
|
||||
return r.json()
|
||||
|
||||
|
||||
@ -325,12 +320,12 @@ def generate_index(): # {{{
|
||||
]
|
||||
body = '<ul class="release-list">{}</ul>'.format(' '.join(body))
|
||||
index = template.format(
|
||||
title='Previous calibre releases (%s.x)' % sname,
|
||||
title='Previous calibre releases ({}.x)'.format(sname),
|
||||
style=style,
|
||||
msg='Choose a calibre release',
|
||||
body=body
|
||||
)
|
||||
with open('%s.html' % sname, 'wb') as f:
|
||||
with open('{}.html'.format(sname), 'wb') as f:
|
||||
f.write(index.encode('utf-8'))
|
||||
|
||||
for r in releases:
|
||||
@ -390,7 +385,7 @@ def generate_index(): # {{{
|
||||
|
||||
body = '<dl>{}</dl>'.format(''.join(body))
|
||||
index = template.format(
|
||||
title='calibre release (%s)' % rname,
|
||||
title='calibre release ({})'.format(rname),
|
||||
style=style,
|
||||
msg='',
|
||||
body=body
|
||||
|
@ -84,7 +84,7 @@ class Hyphenation(ReVendor):
|
||||
NAME = 'hyphenation'
|
||||
TAR_NAME = 'hyphenation dictionaries'
|
||||
VERSION = 'master'
|
||||
DOWNLOAD_URL = 'https://github.com/LibreOffice/dictionaries/archive/%s.tar.gz' % VERSION
|
||||
DOWNLOAD_URL = 'https://github.com/LibreOffice/dictionaries/archive/{}.tar.gz'.format(VERSION)
|
||||
CAN_USE_SYSTEM_VERSION = False
|
||||
|
||||
def run(self, opts):
|
||||
|
@ -288,14 +288,14 @@ class Install(Develop):
|
||||
class Sdist(Command):
|
||||
|
||||
description = 'Create a source distribution'
|
||||
DEST = os.path.join('dist', '%s-%s.tar.xz'%(__appname__, __version__))
|
||||
DEST = os.path.join('dist', '{}-{}.tar.xz'.format(__appname__, __version__))
|
||||
|
||||
def run(self, opts):
|
||||
if not self.e(self.d(self.DEST)):
|
||||
os.makedirs(self.d(self.DEST))
|
||||
tdir = tempfile.mkdtemp()
|
||||
atexit.register(shutil.rmtree, tdir)
|
||||
tdir = self.j(tdir, 'calibre-%s' % __version__)
|
||||
tdir = self.j(tdir, 'calibre-{}'.format(__version__))
|
||||
self.info('\tRunning git export...')
|
||||
os.mkdir(tdir)
|
||||
subprocess.check_call('git archive HEAD | tar -x -C ' + tdir, shell=True)
|
||||
@ -336,7 +336,7 @@ class Sdist(Command):
|
||||
self.info('\tCreating tarfile...')
|
||||
dest = self.DEST.rpartition('.')[0]
|
||||
shutil.rmtree(os.path.join(tdir, '.github'))
|
||||
subprocess.check_call(['tar', '--mtime=now', '-cf', self.a(dest), 'calibre-%s' % __version__], cwd=self.d(tdir))
|
||||
subprocess.check_call(['tar', '--mtime=now', '-cf', self.a(dest), 'calibre-{}'.format(__version__)], cwd=self.d(tdir))
|
||||
self.info('\tCompressing tarfile...')
|
||||
if os.path.exists(self.a(self.DEST)):
|
||||
os.remove(self.a(self.DEST))
|
||||
@ -396,4 +396,4 @@ class Bootstrap(Command):
|
||||
subprocess.check_call(clone_cmd, cwd=self.d(self.SRC))
|
||||
|
||||
def run(self, opts):
|
||||
self.info('\n\nAll done! You should now be able to run "%s setup.py install" to install calibre' % sys.executable)
|
||||
self.info('\n\nAll done! You should now be able to run "{} setup.py install" to install calibre'.format(sys.executable))
|
||||
|
@ -18,7 +18,7 @@ class MathJax(ReVendor):
|
||||
NAME = 'mathjax'
|
||||
TAR_NAME = 'MathJax'
|
||||
VERSION = '3.1.4'
|
||||
DOWNLOAD_URL = 'https://github.com/mathjax/MathJax/archive/%s.tar.gz' % VERSION
|
||||
DOWNLOAD_URL = 'https://github.com/mathjax/MathJax/archive/{}.tar.gz'.format(VERSION)
|
||||
|
||||
def add_file_pre(self, name, raw):
|
||||
self.h.update(raw)
|
||||
|
@ -222,7 +222,7 @@ def get_import_data(name, mod, zf, names):
|
||||
return module
|
||||
raise ValueError(f'Failed to find name: {name!r} in module: {mod!r}')
|
||||
else:
|
||||
raise ValueError('Failed to find module: %r' % mod)
|
||||
raise ValueError('Failed to find module: {!r}'.format(mod))
|
||||
|
||||
|
||||
def parse_metadata(raw, namelist, zf):
|
||||
@ -372,7 +372,7 @@ def fetch_plugin(old_index, entry):
|
||||
raw = read(entry.url).decode('utf-8', 'replace')
|
||||
url, name = parse_plugin_zip_url(raw)
|
||||
if url is None:
|
||||
raise ValueError('Failed to find zip file URL for entry: %s' % repr(entry))
|
||||
raise ValueError('Failed to find zip file URL for entry: {}'.format(repr(entry)))
|
||||
plugin = lm_map.get(entry.thread_id, None)
|
||||
|
||||
if plugin is not None:
|
||||
@ -392,7 +392,7 @@ def fetch_plugin(old_index, entry):
|
||||
slm = datetime(*parsedate(info.get('Last-Modified'))[:6])
|
||||
plugin = get_plugin_info(raw)
|
||||
plugin['last_modified'] = slm.isoformat()
|
||||
plugin['file'] = 'staging_%s.zip' % entry.thread_id
|
||||
plugin['file'] = 'staging_{}.zip'.format(entry.thread_id)
|
||||
plugin['size'] = len(raw)
|
||||
plugin['original_url'] = url
|
||||
update_plugin_from_entry(plugin, entry)
|
||||
@ -460,28 +460,28 @@ def plugin_to_index(plugin, count):
|
||||
quoteattr(plugin['thread_url']), escape(plugin['name']))
|
||||
released = datetime(*tuple(map(int, re.split(r'\D', plugin['last_modified'])))[:6]).strftime('%e %b, %Y').lstrip()
|
||||
details = [
|
||||
'Version: <b>%s</b>' % escape('.'.join(map(str, plugin['version']))),
|
||||
'Released: <b>%s</b>' % escape(released),
|
||||
'Author: %s' % escape(plugin['author']),
|
||||
'calibre: %s' % escape('.'.join(map(str, plugin['minimum_calibre_version']))),
|
||||
'Platforms: %s' % escape(', '.join(sorted(plugin['supported_platforms']) or ['all'])),
|
||||
'Version: <b>{}</b>'.format(escape('.'.join(map(str, plugin['version'])))),
|
||||
'Released: <b>{}</b>'.format(escape(released)),
|
||||
'Author: {}'.format(escape(plugin['author'])),
|
||||
'calibre: {}'.format(escape('.'.join(map(str, plugin['minimum_calibre_version'])))),
|
||||
'Platforms: {}'.format(escape(', '.join(sorted(plugin['supported_platforms']) or ['all']))),
|
||||
]
|
||||
if plugin['uninstall']:
|
||||
details.append('Uninstall: %s' % escape(', '.join(plugin['uninstall'])))
|
||||
details.append('Uninstall: {}'.format(escape(', '.join(plugin['uninstall']))))
|
||||
if plugin['donate']:
|
||||
details.append('<a href=%s title="Donate">Donate</a>' % quoteattr(plugin['donate']))
|
||||
details.append('<a href={} title="Donate">Donate</a>'.format(quoteattr(plugin['donate'])))
|
||||
block = []
|
||||
for li in details:
|
||||
if li.startswith('calibre:'):
|
||||
block.append('<br>')
|
||||
block.append('<li>%s</li>' % li)
|
||||
block = '<ul>%s</ul>' % ('\n'.join(block))
|
||||
block.append('<li>{}</li>'.format(li))
|
||||
block = '<ul>{}</ul>'.format('\n'.join(block))
|
||||
downloads = ('\xa0<span class="download-count">[%d total downloads]</span>' % count) if count else ''
|
||||
zipfile = '<div class="end"><a href={} title="Download plugin" download={}>Download plugin \u2193</a>{}</div>'.format(
|
||||
quoteattr(plugin['file']), quoteattr(plugin['name'] + '.zip'), downloads)
|
||||
desc = plugin['description'] or ''
|
||||
if desc:
|
||||
desc = '<p>%s</p>' % desc
|
||||
desc = '<p>{}</p>'.format(desc)
|
||||
return f'{title}\n{desc}\n{block}\n{zipfile}\n\n'
|
||||
|
||||
|
||||
@ -502,25 +502,25 @@ def create_index(index, raw_stats):
|
||||
<head><meta charset="utf-8"><title>Index of calibre plugins</title>
|
||||
<link rel="icon" type="image/x-icon" href="//calibre-ebook.com/favicon.ico" />
|
||||
<style type="text/css">
|
||||
body { background-color: #eee; }
|
||||
a { text-decoration: none }
|
||||
a:hover, h3:hover { color: red }
|
||||
a:visited { color: blue }
|
||||
ul { list-style-type: none; font-size: smaller }
|
||||
li { display: inline }
|
||||
li+li:before { content: " - " }
|
||||
.end { border-bottom: solid 1pt black; padding-bottom: 0.5ex; margin-bottom: 4ex; }
|
||||
h1 img, h3 img { vertical-align: middle; margin-right: 0.5em; }
|
||||
h1 { text-align: center }
|
||||
.download-count { color: gray; font-size: smaller }
|
||||
body {{ background-color: #eee; }}
|
||||
a {{ text-decoration: none }}
|
||||
a:hover, h3:hover {{ color: red }}
|
||||
a:visited {{ color: blue }}
|
||||
ul {{ list-style-type: none; font-size: smaller }}
|
||||
li {{ display: inline }}
|
||||
li+li:before {{ content: " - " }}
|
||||
.end {{ border-bottom: solid 1pt black; padding-bottom: 0.5ex; margin-bottom: 4ex; }}
|
||||
h1 img, h3 img {{ vertical-align: middle; margin-right: 0.5em; }}
|
||||
h1 {{ text-align: center }}
|
||||
.download-count {{ color: gray; font-size: smaller }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1><img src="//manual.calibre-ebook.com/_static/logo.png">Index of calibre plugins</h1>
|
||||
<div style="text-align:center"><a href="stats.html">Download counts for all plugins</a></div>
|
||||
%s
|
||||
{}
|
||||
</body>
|
||||
</html>''' % ('\n'.join(plugins))
|
||||
</html>'''.format('\n'.join(plugins))
|
||||
raw = index.encode('utf-8')
|
||||
try:
|
||||
with open('index.html', 'rb') as f:
|
||||
@ -541,20 +541,20 @@ h1 { text-align: center }
|
||||
<head><meta charset="utf-8"><title>Stats for calibre plugins</title>
|
||||
<link rel="icon" type="image/x-icon" href="//calibre-ebook.com/favicon.ico" />
|
||||
<style type="text/css">
|
||||
body { background-color: #eee; }
|
||||
h1 img, h3 img { vertical-align: middle; margin-right: 0.5em; }
|
||||
h1 { text-align: center }
|
||||
body {{ background-color: #eee; }}
|
||||
h1 img, h3 img {{ vertical-align: middle; margin-right: 0.5em; }}
|
||||
h1 {{ text-align: center }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1><img src="//manual.calibre-ebook.com/_static/logo.png">Stats for calibre plugins</h1>
|
||||
<table>
|
||||
<tr><th>Plugin</th><th>Total downloads</th></tr>
|
||||
%s
|
||||
{}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
''' % ('\n'.join(pstats))
|
||||
'''.format('\n'.join(pstats))
|
||||
raw = stats.encode('utf-8')
|
||||
try:
|
||||
with open('stats.html', 'rb') as f:
|
||||
|
@ -68,7 +68,7 @@ class Stage2(Command):
|
||||
installer = self.j(self.d(self.SRC), installer)
|
||||
if not os.path.exists(installer) or os.path.getsize(installer) < 10000:
|
||||
raise SystemExit(
|
||||
'The installer %s does not exist' % os.path.basename(installer)
|
||||
'The installer {} does not exist'.format(os.path.basename(installer))
|
||||
)
|
||||
|
||||
|
||||
@ -129,8 +129,7 @@ class PublishBetas(Command):
|
||||
def run(self, opts):
|
||||
dist = self.a(self.j(self.d(self.SRC), 'dist'))
|
||||
subprocess.check_call((
|
||||
'rsync --partial -rh --info=progress2 --delete-after %s/ download.calibre-ebook.com:/srv/download/betas/'
|
||||
% dist
|
||||
'rsync --partial -rh --info=progress2 --delete-after {}/ download.calibre-ebook.com:/srv/download/betas/'.format(dist)
|
||||
).split())
|
||||
|
||||
|
||||
@ -203,7 +202,7 @@ class Manual(Command):
|
||||
jobs.append(create_job([
|
||||
sys.executable, self.j(self.d(self.SRC), 'manual', 'build.py'),
|
||||
language, self.j(tdir, language)
|
||||
], '\n\n**************** Building translations for: %s' % language))
|
||||
], '\n\n**************** Building translations for: {}'.format(language)))
|
||||
self.info('Building manual for %d languages' % len(jobs))
|
||||
subprocess.check_call(jobs[0].cmd)
|
||||
if not parallel_build(jobs[1:], self.info):
|
||||
@ -299,7 +298,7 @@ class ManPages(Command):
|
||||
for l in languages:
|
||||
jobs.append(create_job(
|
||||
[sys.executable, self.j(base, 'build.py'), '--man-pages', l, dest],
|
||||
'\n\n**************** Building translations for: %s' % l)
|
||||
'\n\n**************** Building translations for: {}'.format(l))
|
||||
)
|
||||
self.info(f'\tCreating man pages in {dest} for {len(jobs)} languages...')
|
||||
subprocess.check_call(jobs[0].cmd)
|
||||
|
@ -16,12 +16,12 @@ class ReVendor(Command):
|
||||
CAN_USE_SYSTEM_VERSION = True
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option('--path-to-%s' % self.NAME, help='Path to the extracted %s source' % self.TAR_NAME)
|
||||
parser.add_option('--%s-url' % self.NAME, default=self.DOWNLOAD_URL,
|
||||
help='URL to %s source archive in tar.gz format' % self.TAR_NAME)
|
||||
parser.add_option('--path-to-{}'.format(self.NAME), help='Path to the extracted {} source'.format(self.TAR_NAME))
|
||||
parser.add_option('--{}-url'.format(self.NAME), default=self.DOWNLOAD_URL,
|
||||
help='URL to {} source archive in tar.gz format'.format(self.TAR_NAME))
|
||||
if self.CAN_USE_SYSTEM_VERSION:
|
||||
parser.add_option('--system-%s' % self.NAME, default=False, action='store_true',
|
||||
help='Treat %s as system copy and symlink instead of copy' % self.TAR_NAME)
|
||||
parser.add_option('--system-{}'.format(self.NAME), default=False, action='store_true',
|
||||
help='Treat {} as system copy and symlink instead of copy'.format(self.TAR_NAME))
|
||||
|
||||
def download_securely(self, url: str) -> bytes:
|
||||
num = 5 if is_ci else 1
|
||||
@ -35,7 +35,7 @@ class ReVendor(Command):
|
||||
time.sleep(2)
|
||||
|
||||
def download_vendor_release(self, tdir, url):
|
||||
self.info('Downloading %s:' % self.TAR_NAME, url)
|
||||
self.info('Downloading {}:'.format(self.TAR_NAME), url)
|
||||
raw = self.download_securely(url)
|
||||
with tarfile.open(fileobj=BytesIO(raw)) as tf:
|
||||
tf.extractall(tdir)
|
||||
|
@ -37,14 +37,14 @@ class Test(BaseTest):
|
||||
super().add_options(parser)
|
||||
parser.add_option('--test-verbosity', type=int, default=4, help='Test verbosity (0-4)')
|
||||
parser.add_option('--test-module', '--test-group', default=[], action='append', type='choice', choices=sorted(map(str, TEST_MODULES)),
|
||||
help='The test module to run (can be specified more than once for multiple modules). Choices: %s' % ', '.join(sorted(TEST_MODULES)))
|
||||
help='The test module to run (can be specified more than once for multiple modules). Choices: {}'.format(', '.join(sorted(TEST_MODULES))))
|
||||
parser.add_option('--test-name', '-n', default=[], action='append',
|
||||
help='The name of an individual test to run. Can be specified more than once for multiple tests. The name of the'
|
||||
' test is the name of the test function without the leading test_. For example, the function test_something()'
|
||||
' can be run by specifying the name "something".')
|
||||
parser.add_option('--exclude-test-module', default=[], action='append', type='choice', choices=sorted(map(str, TEST_MODULES)),
|
||||
help='A test module to be excluded from the test run (can be specified more than once for multiple modules).'
|
||||
' Choices: %s' % ', '.join(sorted(TEST_MODULES)))
|
||||
' Choices: {}'.format(', '.join(sorted(TEST_MODULES))))
|
||||
parser.add_option('--exclude-test-name', default=[], action='append',
|
||||
help='The name of an individual test to be excluded from the test run. Can be specified more than once for multiple tests.')
|
||||
|
||||
|
@ -97,7 +97,7 @@ class POT(Command): # {{{
|
||||
slash = codepoint_to_chr(92)
|
||||
msg = msg.replace(slash, slash*2).replace('"', r'\"').replace('\n',
|
||||
r'\n').replace('\r', r'\r').replace('\t', r'\t')
|
||||
ans.append('msgid "%s"'%msg)
|
||||
ans.append('msgid "{}"'.format(msg))
|
||||
ans.append('msgstr ""')
|
||||
ans.append('')
|
||||
|
||||
@ -135,8 +135,8 @@ class POT(Command): # {{{
|
||||
lines = f.read().decode('utf-8').splitlines()
|
||||
for i in range(len(lines)):
|
||||
line = lines[i].strip()
|
||||
if line == '[calibre.%s]' % slug:
|
||||
lines.insert(i+1, 'file_filter = manual/<lang>/%s.po' % bname)
|
||||
if line == '[calibre.{}]'.format(slug):
|
||||
lines.insert(i+1, 'file_filter = manual/<lang>/{}.po'.format(bname))
|
||||
f.seek(0), f.truncate(), f.write('\n'.join(lines).encode('utf-8'))
|
||||
break
|
||||
else:
|
||||
@ -397,12 +397,12 @@ class Translations(POT): # {{{
|
||||
iso_data.extract_po_files('iso_639-3', tdir)
|
||||
for f, (locale, dest) in iteritems(fmap):
|
||||
iscpo = {'zh_HK':'zh_CN'}.get(locale, locale)
|
||||
iso639 = self.j(tdir, '%s.po'%iscpo)
|
||||
iso639 = self.j(tdir, '{}.po'.format(iscpo))
|
||||
if os.path.exists(iso639):
|
||||
files.append((iso639, self.j(self.d(dest), 'iso639.mo')))
|
||||
else:
|
||||
iscpo = iscpo.partition('_')[0]
|
||||
iso639 = self.j(tdir, '%s.po'%iscpo)
|
||||
iso639 = self.j(tdir, '{}.po'.format(iscpo))
|
||||
if os.path.exists(iso639):
|
||||
files.append((iso639, self.j(self.d(dest), 'iso639.mo')))
|
||||
elif locale not in skip_iso:
|
||||
|
@ -74,7 +74,7 @@ def upload_signatures():
|
||||
for srv in 'code main'.split():
|
||||
check_call(scp + ['{0}:/srv/{0}/signatures/'.format(srv)])
|
||||
check_call(
|
||||
['ssh', srv, 'chown', '-R', 'http:http', '/srv/%s/signatures' % srv]
|
||||
['ssh', srv, 'chown', '-R', 'http:http', '/srv/{}/signatures'.format(srv)]
|
||||
)
|
||||
finally:
|
||||
shutil.rmtree(tdir)
|
||||
@ -367,18 +367,18 @@ class UploadDemo(Command): # {{{
|
||||
|
||||
def run(self, opts):
|
||||
check_call(
|
||||
'''ebook-convert %s/demo.html /tmp/html2lrf.lrf '''
|
||||
'''ebook-convert {}/demo.html /tmp/html2lrf.lrf '''
|
||||
'''--title='Demonstration of html2lrf' --authors='Kovid Goyal' '''
|
||||
'''--header '''
|
||||
'''--serif-family "/usr/share/fonts/corefonts, Times New Roman" '''
|
||||
'''--mono-family "/usr/share/fonts/corefonts, Andale Mono" '''
|
||||
'''''' % self.j(self.SRC, HTML2LRF),
|
||||
''''''.format(self.j(self.SRC, HTML2LRF)),
|
||||
shell=True
|
||||
)
|
||||
|
||||
lrf = self.j(self.SRC, 'calibre', 'ebooks', 'lrf', 'html', 'demo')
|
||||
check_call(
|
||||
'cd %s && zip -j /tmp/html-demo.zip * /tmp/html2lrf.lrf' % lrf,
|
||||
'cd {} && zip -j /tmp/html-demo.zip * /tmp/html2lrf.lrf'.format(lrf),
|
||||
shell=True
|
||||
)
|
||||
|
||||
@ -409,8 +409,7 @@ class UploadToServer(Command): # {{{
|
||||
('ssh code /apps/update-calibre-version.py ' + __version__).split()
|
||||
)
|
||||
check_call((
|
||||
'ssh main /usr/local/bin/update-calibre-version.py %s && /usr/local/bin/update-calibre-code.py && /apps/static/generate.py'
|
||||
% __version__
|
||||
'ssh main /usr/local/bin/update-calibre-version.py {} && /usr/local/bin/update-calibre-code.py && /apps/static/generate.py'.format(__version__)
|
||||
).split())
|
||||
|
||||
|
||||
|
@ -100,7 +100,7 @@ def main():
|
||||
else:
|
||||
if len(sys.argv) == 1:
|
||||
raise SystemExit('Usage: win-ci.py sw|build|test')
|
||||
raise SystemExit('%r is not a valid action' % sys.argv[-1])
|
||||
raise SystemExit('{!r} is not a valid action'.format(sys.argv[-1]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -50,7 +50,7 @@ pattern_vector3D = re.compile(r'\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)([ ]+-?([0-9
|
||||
|
||||
def make_NCName(arg):
|
||||
for c in (':',' '):
|
||||
arg = arg.replace(c,'_%x_' % ord(c))
|
||||
arg = arg.replace(c,'_{:x}_'.format(ord(c)))
|
||||
return arg
|
||||
|
||||
|
||||
@ -78,13 +78,13 @@ def cnv_color(attribute, arg, element):
|
||||
def cnv_configtype(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('boolean', 'short', 'int', 'long',
|
||||
'double', 'string', 'datetime', 'base64Binary'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
|
||||
def cnv_data_source_has_labels(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('none','row','column','both'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
# Understand different date formats
|
||||
@ -116,7 +116,7 @@ def cnv_family(attribute, arg, element):
|
||||
''' A style family '''
|
||||
if unicode_type(arg) not in ('text', 'paragraph', 'section', 'ruby', 'table', 'table-column', 'table-row', 'table-cell',
|
||||
'graphic', 'presentation', 'drawing-page', 'chart'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ def cnv_integer(attribute, arg, element):
|
||||
|
||||
def cnv_legend_position(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('start', 'end', 'top', 'bottom', 'top-start', 'bottom-start', 'top-end', 'bottom-end'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
|
||||
@ -167,7 +167,7 @@ def cnv_length(attribute, arg, element):
|
||||
'''
|
||||
global pattern_length
|
||||
if not pattern_length.match(arg):
|
||||
raise ValueError("'%s' is not a valid length" % arg)
|
||||
raise ValueError("'{}' is not a valid length".format(arg))
|
||||
return arg
|
||||
|
||||
|
||||
@ -182,19 +182,19 @@ def cnv_lengthorpercent(attribute, arg, element):
|
||||
except:
|
||||
failed = True
|
||||
if failed:
|
||||
raise ValueError("'%s' is not a valid length or percent" % arg)
|
||||
raise ValueError("'{}' is not a valid length or percent".format(arg))
|
||||
return arg
|
||||
|
||||
|
||||
def cnv_metavaluetype(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('float', 'date', 'time', 'boolean', 'string'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
|
||||
def cnv_major_minor(attribute, arg, element):
|
||||
if arg not in ('major','minor'):
|
||||
raise ValueError("'%s' is not either 'minor' or 'major'" % arg)
|
||||
raise ValueError("'{}' is not either 'minor' or 'major'".format(arg))
|
||||
|
||||
|
||||
pattern_namespacedToken = re.compile(r'[0-9a-zA-Z_]+:[0-9a-zA-Z._\-]+')
|
||||
@ -204,7 +204,7 @@ 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)
|
||||
raise ValueError("'{}' is not a valid namespaced token".format(arg))
|
||||
return __save_prefix(attribute, arg, element)
|
||||
|
||||
|
||||
@ -258,7 +258,7 @@ 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)
|
||||
raise ValueError("'{}' is not a valid length".format(arg))
|
||||
return arg
|
||||
|
||||
|
||||
@ -277,7 +277,7 @@ def cnv_points(attribute, arg, element):
|
||||
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)
|
||||
raise ValueError('Points must be string or [(0,0),(1,1)] - not {}'.format(arg))
|
||||
return strarg
|
||||
|
||||
|
||||
@ -291,7 +291,7 @@ def cnv_string(attribute, arg, element):
|
||||
|
||||
def cnv_textnoteclass(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('footnote', 'endnote'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
# Understand different time formats
|
||||
@ -317,7 +317,7 @@ def cnv_viewbox(attribute, arg, element):
|
||||
|
||||
def cnv_xlinkshow(attribute, arg, element):
|
||||
if unicode_type(arg) not in ('new', 'replace', 'embed'):
|
||||
raise ValueError("'%s' not allowed" % unicode_type(arg))
|
||||
raise ValueError("'{}' not allowed".format(unicode_type(arg)))
|
||||
return unicode_type(arg)
|
||||
|
||||
|
||||
|
@ -67,11 +67,11 @@ def _quoteattr(data, entities={}):
|
||||
data = _escape(data, entities)
|
||||
if '"' in data:
|
||||
if "'" in data:
|
||||
data = '"%s"' % data.replace('"', '"')
|
||||
data = '"{}"'.format(data.replace('"', '"'))
|
||||
else:
|
||||
data = "'%s'" % data
|
||||
data = "'{}'".format(data)
|
||||
else:
|
||||
data = '"%s"' % data
|
||||
data = '"{}"'.format(data)
|
||||
return data
|
||||
|
||||
|
||||
@ -275,7 +275,7 @@ class CDATASection(Text, Childless):
|
||||
and then go into CDATA mode again. (<![CDATA[)
|
||||
'''
|
||||
if self.data:
|
||||
f.write('<![CDATA[%s]]>' % self.data.replace(']]>',']]>]]><![CDATA['))
|
||||
f.write('<![CDATA[{}]]>'.format(self.data.replace(']]>',']]>]]><![CDATA[')))
|
||||
|
||||
|
||||
class Element(Node):
|
||||
@ -383,7 +383,7 @@ class Element(Node):
|
||||
Setting check_grammar=False turns off grammar checking
|
||||
'''
|
||||
if check_grammar and self.qname not in grammar.allows_text:
|
||||
raise IllegalText('The <%s> element does not allow text' % self.tagName)
|
||||
raise IllegalText('The <{}> element does not allow text'.format(self.tagName))
|
||||
else:
|
||||
if text != '':
|
||||
self.appendChild(Text(text))
|
||||
@ -393,7 +393,7 @@ class Element(Node):
|
||||
Setting check_grammar=False turns off grammar checking
|
||||
'''
|
||||
if check_grammar and self.qname not in grammar.allows_text:
|
||||
raise IllegalText('The <%s> element does not allow text' % self.tagName)
|
||||
raise IllegalText('The <{}> element does not allow text'.format(self.tagName))
|
||||
else:
|
||||
self.appendChild(CDATASection(cdata))
|
||||
|
||||
|
@ -75,7 +75,7 @@ class LoadParser(handler.ContentHandler):
|
||||
e = Element(qname=tag, qattributes=attrdict, check_grammar=False)
|
||||
self.curr = e
|
||||
except AttributeError as v:
|
||||
print('Error: %s' % v)
|
||||
print('Error: {}'.format(v))
|
||||
|
||||
if tag == (OFFICENS, 'automatic-styles'):
|
||||
e = self.doc.automaticstyles
|
||||
|
@ -326,16 +326,16 @@ class ODF2MoinMoin:
|
||||
|
||||
link = node.getAttribute('xlink:href')
|
||||
if link and link[:2] == './': # Indicates a sub-object, which isn't supported
|
||||
return '%s\n' % link
|
||||
return '{}\n'.format(link)
|
||||
if link and link[:9] == 'Pictures/':
|
||||
link = link[9:]
|
||||
return '[[Image(%s)]]\n' % link
|
||||
return '[[Image({})]]\n'.format(link)
|
||||
|
||||
def text_a(self, node):
|
||||
text = self.textToString(node)
|
||||
link = node.getAttribute('xlink:href')
|
||||
if link.strip() == text.strip():
|
||||
return '[%s] ' % link.strip()
|
||||
return '[{}] '.format(link.strip())
|
||||
else:
|
||||
return f'[{link.strip()} {text.strip()}] '
|
||||
|
||||
@ -348,7 +348,7 @@ class ODF2MoinMoin:
|
||||
body = (node.getElementsByTagName('text:note-body')[0]
|
||||
.childNodes[0])
|
||||
self.footnotes.append((cite, self.textToString(body)))
|
||||
return '^%s^' % cite
|
||||
return '^{}^'.format(cite)
|
||||
|
||||
def text_s(self, node):
|
||||
try:
|
||||
|
@ -161,7 +161,7 @@ class StyleToCSS:
|
||||
this should really be implemented as an absolutely position <img>
|
||||
with a width and a height
|
||||
'''
|
||||
sdict['background-image'] = "url('%s')" % self.fillimages[val]
|
||||
sdict['background-image'] = "url('{}')".format(self.fillimages[val])
|
||||
|
||||
def c_fo(self, ruleset, sdict, rule, val):
|
||||
''' XSL formatting attributes '''
|
||||
@ -203,7 +203,7 @@ class StyleToCSS:
|
||||
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)
|
||||
sdict['font-family'] = '{}, {}'.format(family, htmlgeneric)
|
||||
|
||||
def c_text_position(self, ruleset, sdict, rule, tp):
|
||||
''' Text position. This is used e.g. to make superscript and subscript
|
||||
@ -510,7 +510,7 @@ class ODF2XHTML(handler.ContentHandler):
|
||||
if media:
|
||||
self.metatags.append(f'<link rel="stylesheet" type="text/css" href="{stylefilename}" media="{media}"/>\n')
|
||||
else:
|
||||
self.metatags.append('<link rel="stylesheet" type="text/css" href="%s"/>\n' % (stylefilename))
|
||||
self.metatags.append('<link rel="stylesheet" type="text/css" href="{}"/>\n'.format(stylefilename))
|
||||
|
||||
def _resetfootnotes(self):
|
||||
# Footnotes and endnotes
|
||||
@ -564,7 +564,7 @@ class ODF2XHTML(handler.ContentHandler):
|
||||
for key,val in attrs.items():
|
||||
a.append(f'''{key}={quoteattr(val)}''')
|
||||
if len(a) == 0:
|
||||
self.writeout('<%s>' % tag)
|
||||
self.writeout('<{}>'.format(tag))
|
||||
else:
|
||||
self.writeout('<{} {}>'.format(tag, ' '.join(a)))
|
||||
if block:
|
||||
@ -573,7 +573,7 @@ class ODF2XHTML(handler.ContentHandler):
|
||||
def closetag(self, tag, block=True):
|
||||
''' Close an open HTML tag '''
|
||||
self.htmlstack.pop()
|
||||
self.writeout('</%s>' % tag)
|
||||
self.writeout('</{}>'.format(tag))
|
||||
if block:
|
||||
self.writeout('\n')
|
||||
|
||||
@ -675,14 +675,14 @@ class ODF2XHTML(handler.ContentHandler):
|
||||
''' Set the content language. Identifies the targeted audience
|
||||
'''
|
||||
self.language = ''.join(self.data)
|
||||
self.metatags.append('<meta http-equiv="content-language" content="%s"/>\n' % escape(self.language))
|
||||
self.metatags.append('<meta http-equiv="content-language" content="{}"/>\n'.format(escape(self.language)))
|
||||
self.data = []
|
||||
|
||||
def e_dc_creator(self, tag, attrs):
|
||||
''' Set the content creator. Identifies the targeted audience
|
||||
'''
|
||||
self.creator = ''.join(self.data)
|
||||
self.metatags.append('<meta http-equiv="creator" content="%s"/>\n' % escape(self.creator))
|
||||
self.metatags.append('<meta http-equiv="creator" content="{}"/>\n'.format(escape(self.creator)))
|
||||
self.data = []
|
||||
|
||||
def s_custom_shape(self, tag, attrs):
|
||||
@ -923,7 +923,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
yield k, v
|
||||
|
||||
for css2, names in css_styles.items():
|
||||
self.writeout('%s {\n' % ', '.join(names))
|
||||
self.writeout('{} {{\n'.format(', '.join(names)))
|
||||
for style, val in filter_margins(css2):
|
||||
self.writeout(f'\t{style}: {val};\n')
|
||||
self.writeout('}\n')
|
||||
@ -970,7 +970,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
self.emptytag('meta', {'http-equiv':'Content-Type', 'content':'text/html;charset=UTF-8'})
|
||||
for metaline in self.metatags:
|
||||
self.writeout(metaline)
|
||||
self.writeout('<title>%s</title>\n' % escape(self.title))
|
||||
self.writeout('<title>{}</title>\n'.format(escape(self.title)))
|
||||
|
||||
def e_office_document_content(self, tag, attrs):
|
||||
''' Last tag '''
|
||||
@ -1172,7 +1172,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
c = attrs.get((TABLENS,'style-name'), None)
|
||||
if c and self.generate_css:
|
||||
c = c.replace('.','_')
|
||||
self.opentag('table',{'class': 'T-%s' % c})
|
||||
self.opentag('table',{'class': 'T-{}'.format(c)})
|
||||
else:
|
||||
self.opentag('table')
|
||||
self.purgedata()
|
||||
@ -1198,7 +1198,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
|
||||
c = attrs.get((TABLENS,'style-name'))
|
||||
if c:
|
||||
htmlattrs['class'] = 'TD-%s' % c.replace('.','_')
|
||||
htmlattrs['class'] = 'TD-{}'.format(c.replace('.','_'))
|
||||
self.opentag('td', htmlattrs)
|
||||
self.purgedata()
|
||||
|
||||
@ -1214,7 +1214,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
repeated = int(attrs.get((TABLENS,'number-columns-repeated'), 1))
|
||||
htmlattrs = {}
|
||||
if c:
|
||||
htmlattrs['class'] = 'TC-%s' % c.replace('.','_')
|
||||
htmlattrs['class'] = 'TC-{}'.format(c.replace('.','_'))
|
||||
for x in range(repeated):
|
||||
self.emptytag('col', htmlattrs)
|
||||
self.purgedata()
|
||||
@ -1225,7 +1225,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
c = attrs.get((TABLENS,'style-name'), None)
|
||||
htmlattrs = {}
|
||||
if c:
|
||||
htmlattrs['class'] = 'TR-%s' % c.replace('.','_')
|
||||
htmlattrs['class'] = 'TR-{}'.format(c.replace('.','_'))
|
||||
self.opentag('tr', htmlattrs)
|
||||
self.purgedata()
|
||||
|
||||
@ -1280,9 +1280,9 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
self.headinglevels[x] = 0
|
||||
special = special_styles.get('P-'+name)
|
||||
if special or not self.generate_css:
|
||||
self.opentag('h%s' % level)
|
||||
self.opentag('h{}'.format(level))
|
||||
else:
|
||||
self.opentag('h%s' % level, {'class':'P-%s' % name})
|
||||
self.opentag('h{}'.format(level), {'class':'P-{}'.format(name)})
|
||||
self.purgedata()
|
||||
|
||||
def e_text_h(self, tag, attrs):
|
||||
@ -1309,7 +1309,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
self.closetag('a', False)
|
||||
self.opentag('a', {'id': anchor2})
|
||||
self.closetag('a', False)
|
||||
self.closetag('h%s' % level)
|
||||
self.closetag('h{}'.format(level))
|
||||
self.purgedata()
|
||||
|
||||
def s_text_line_break(self, tag, attrs):
|
||||
@ -1355,7 +1355,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
attrs = {'start': unicode_type(self.list_number_map[number_class])}
|
||||
if self.generate_css:
|
||||
attrs['class'] = list_class
|
||||
self.opentag('%s' % tag_name, attrs)
|
||||
self.opentag('{}'.format(tag_name), attrs)
|
||||
self.purgedata()
|
||||
|
||||
def e_text_list(self, tag, attrs):
|
||||
@ -1473,9 +1473,9 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
self.notedict[self.currentnote]['citation'] = mark
|
||||
self.opentag('sup')
|
||||
self.opentag('a', {
|
||||
'href': '#footnote-%s' % self.currentnote,
|
||||
'href': '#footnote-{}'.format(self.currentnote),
|
||||
'class': 'citation',
|
||||
'id':'citation-%s' % self.currentnote
|
||||
'id':'citation-{}'.format(self.currentnote)
|
||||
})
|
||||
# self.writeout( escape(mark) )
|
||||
# Since HTML only knows about endnotes, there is too much risk that the
|
||||
@ -1496,7 +1496,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
if specialtag is None:
|
||||
specialtag = 'p'
|
||||
if self.generate_css:
|
||||
htmlattrs['class'] = 'P-%s' % c
|
||||
htmlattrs['class'] = 'P-{}'.format(c)
|
||||
self.opentag(specialtag, htmlattrs)
|
||||
self.purgedata()
|
||||
|
||||
@ -1548,7 +1548,7 @@ dl.notes dd:last-of-type { page-break-after: avoid }
|
||||
if special is None:
|
||||
special = 'span'
|
||||
if self.generate_css:
|
||||
htmlattrs['class'] = 'S-%s' % c
|
||||
htmlattrs['class'] = 'S-{}'.format(c)
|
||||
|
||||
self.opentag(special, htmlattrs)
|
||||
self.purgedata()
|
||||
|
@ -388,7 +388,7 @@ class OpenDocument:
|
||||
document.folder = '%s/Object %d' % (self.folder, len(self.childobjects))
|
||||
else:
|
||||
document.folder = objectname
|
||||
return '.%s' % document.folder
|
||||
return '.{}'.format(document.folder)
|
||||
|
||||
def _savePictures(self, object, folder):
|
||||
for arcname, picturerec in object.Pictures.items():
|
||||
@ -492,23 +492,23 @@ class OpenDocument:
|
||||
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)
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath='{}styles.xml'.format(folder), mediatype='text/xml'))
|
||||
zi = zipfile.ZipInfo('{}styles.xml'.format(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)
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath='{}content.xml'.format(folder), mediatype='text/xml'))
|
||||
zi = zipfile.ZipInfo('{}content.xml'.format(folder), self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.contentxml())
|
||||
|
||||
# Write settings
|
||||
if object.settings.hasChildNodes():
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath='%ssettings.xml' % folder, mediatype='text/xml'))
|
||||
zi = zipfile.ZipInfo('%ssettings.xml' % folder, self._now)
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath='{}settings.xml'.format(folder), mediatype='text/xml'))
|
||||
zi = zipfile.ZipInfo('{}settings.xml'.format(folder), self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.settingsxml())
|
||||
|
@ -65,7 +65,7 @@ class UserFields:
|
||||
if isinstance(self.src_file, (bytes, str)):
|
||||
# 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)
|
||||
raise TypeError('{} is no odt file.'.format(self.src_file))
|
||||
elif self.src_file is None:
|
||||
# use stdin if no file given
|
||||
self.src_file = sys.stdin
|
||||
|
Loading…
x
Reference in New Issue
Block a user