This commit is contained in:
Eli Schwartz 2019-03-24 00:54:22 -04:00
parent a623717d96
commit 4f545af415
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
47 changed files with 137 additions and 65 deletions

View File

@ -12,6 +12,7 @@ class Bookmark(): # {{{
A simple class fetching bookmark data
kobo-specific
'''
def __init__(self, db_connection, contentid, path, id, book_format, bookmark_extension):
self.book_format = book_format
self.bookmark_extension = bookmark_extension

View File

@ -39,6 +39,7 @@ class Field(object):
self.instructions = ''.join(self.buf)
del self.buf
WORD, FLAG = 0, 1
scanner = re.Scanner([
(r'\\\S{1}', lambda s, t: (t, FLAG)), # A flag of the form \x
@ -77,6 +78,7 @@ def parser(name, field_map, default_field_name=None):
return parse
parse_hyperlink = parser('hyperlink',
'l:anchor m:image-map n:target o:title t:target', 'url')
@ -257,5 +259,6 @@ def test_parse_fields(return_tests=False):
return suite
unittest.TextTestRunner(verbosity=4).run(suite)
if __name__ == '__main__':
test_parse_fields()

View File

@ -37,6 +37,7 @@ def alphabet(val, lower=True):
x = string.ascii_lowercase if lower else string.ascii_uppercase
return x[(abs(val - 1)) % len(x)]
alphabet_map = {
'lower-alpha':alphabet, 'upper-alpha':partial(alphabet, lower=False),
'lower-roman':lambda x:roman(x).lower(), 'upper-roman':roman,

View File

@ -652,7 +652,7 @@ class LrfWriter(object):
return self.sourceEncoding
def toUnicode(self, string):
if type(string) is str:
if isinstance(string, str):
string = string.decode(self.sourceEncoding)
return string

View File

@ -67,10 +67,10 @@ def parse_meta_tags(src):
all_names = '|'.join(rmap)
ans = {}
npat = r'''name\s*=\s*['"]{0,1}(?P<name>%s)['"]{0,1}''' % all_names
cpat = 'content\s*=\s*%s' % attr_pat
cpat = r'content\s*=\s*%s' % attr_pat
for pat in (
'<meta\s+%s\s+%s' % (npat, cpat),
'<meta\s+%s\s+%s' % (cpat, npat),
r'<meta\s+%s\s+%s' % (npat, cpat),
r'<meta\s+%s\s+%s' % (cpat, npat),
):
for match in re.finditer(pat, src, flags=re.IGNORECASE):
x = match.group('name').lower()

View File

@ -65,5 +65,6 @@ def import_book_as_epub(srcpath, destpath, log=default_log):
for name in c.name_path_map:
zf.writestr(name, c.raw_data(name, decode=False))
if __name__ == '__main__':
import_book_as_epub(sys.argv[-2], sys.argv[-1])

View File

@ -89,6 +89,7 @@ def get_split_book(fmt='epub'):
os.remove(x)
return ans
devnull = DevNull()

View File

@ -121,7 +121,7 @@ def create_markdown_object(extensions):
if hasattr(module, 'makeExtension'):
return module.makeExtension(**configs)
for name, x in vars(module).items():
if type(x) is type and issubclass(x, Extension) and x is not Extension:
if isinstance(x, type) and issubclass(x, Extension) and x is not Extension:
return x(**configs)
raise ImportError('No extension class in {}'.format(ext_name))

View File

@ -46,7 +46,7 @@ class CoverCache(dict):
def _pop(self, book_id):
val = self.items.pop(book_id, None)
if type(val) is QPixmap and current_thread() is not self.gui_thread:
if isinstance(val, QPixmap) and current_thread() is not self.gui_thread:
self.pixmap_staging.append(val)
def __getitem__(self, key):
@ -55,7 +55,7 @@ class CoverCache(dict):
self.clear_staging()
ans = self.items.pop(key, False) # pop() so that item is moved to the top
if ans is not False:
if type(ans) is QImage:
if isinstance(ans, QImage):
# Convert to QPixmap, since rendering QPixmap is much
# faster
ans = QPixmap.fromImage(ans)
@ -73,7 +73,7 @@ class CoverCache(dict):
def clear(self):
with self.lock:
if current_thread() is not self.gui_thread:
pixmaps = (x for x in itervalues(self.items) if type(x) is QPixmap)
pixmaps = (x for x in itervalues(self.items) if isinstance(x, QPixmap))
self.pixmap_staging.extend(pixmaps)
self.items.clear()

View File

@ -68,6 +68,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
from calibre.utils.config import config_dir
open_local_file(config_dir)
if __name__ == '__main__':
from PyQt5.Qt import QApplication
app = QApplication([])

View File

@ -139,7 +139,7 @@ def string_diff(left, right, left_syntax=None, right_syntax=None, left_name='lef
def file_diff(left, right):
(raw1, syntax1), (raw2, syntax2) = map(get_decoded_raw, (left, right))
if type(raw1) is not type(raw2):
if not isinstance(raw1, type(raw2)):
raw1, raw2 = open(left, 'rb').read(), open(right, 'rb').read()
cache = Cache()
cache.set_left(left, raw1), cache.set_right(right, raw2)

View File

@ -269,6 +269,7 @@ def in_string(state, text, i, formats, user_data):
state.parse = (NORMAL if state.blocks < 1 else IN_CONTENT)
return [(pos - i + len(q), formats['string'])]
state_map = {
NORMAL:normal,
IN_COMMENT_NORMAL: comment,

View File

@ -32,6 +32,7 @@ def default_theme():
_default_theme = 'wombat-dark' if isdark else 'pyte-light'
return _default_theme
# The solarized themes {{{
SLDX = {'base03':'1c1c1c', 'base02':'262626', 'base01':'585858', 'base00':'626262', 'base0':'808080', 'base1':'8a8a8a', 'base2':'e4e4e4', 'base3':'ffffd7', 'yellow':'af8700', 'orange':'d75f00', 'red':'d70000', 'magenta':'af005f', 'violet':'5f5faf', 'blue':'0087ff', 'cyan':'00afaf', 'green':'5f8700'} # noqa
SLD = {'base03':'002b36', 'base02':'073642', 'base01':'586e75', 'base00':'657b83', 'base0':'839496', 'base1':'93a1a1', 'base2':'eee8d5', 'base3':'fdf6e3', 'yellow':'b58900', 'orange':'cb4b16', 'red':'dc322f', 'magenta':'d33682', 'violet':'6c71c4', 'blue':'268bd2', 'cyan':'2aa198', 'green':'859900'} # noqa

View File

@ -569,8 +569,7 @@ class SearchesModel(QAbstractListModel):
def dropMimeData(self, data, action, row, column, parent):
if parent.isValid() or action != Qt.MoveAction or not data.hasFormat('x-calibre/searches-rows') or not self.filtered_searches:
return False
rows = map(int, bytes(bytearray(data.data('x-calibre/searches-rows'))).decode('ascii').split(','))
rows.sort()
rows = sorted(map(int, bytes(bytearray(data.data('x-calibre/searches-rows'))).decode('ascii').split(',')))
moved_searches = [self.searches[self.filtered_searches[r]] for r in rows]
moved_searches_q = {id(s) for s in moved_searches}
insert_at = max(0, min(row, len(self.filtered_searches)))

View File

@ -144,5 +144,6 @@ def import_from_oxt(source_path, name, dest_dir=None, prefix='dic-'):
num += 1
return num
if __name__ == '__main__':
import_from_libreoffice_source_tree(sys.argv[-1])

View File

@ -388,6 +388,7 @@ def split_name(name):
return l[1:], r
return None, l
boolean_attributes = frozenset('allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible'.split(',')) # noqa
EPUB_TYPE_MAP = {k:'doc-' + k for k in (

View File

@ -142,6 +142,7 @@ class dbus_property(object):
def setter(self, fset):
return self._copy(fset=fset)
_logger = logging.getLogger('dbus.service')

View File

@ -208,8 +208,7 @@ class CmapTable(UnknownTable):
if self.bmp_table is None:
raise UnsupportedFont('This font has no Windows BMP cmap subtable.'
' Most likely a special purpose font.')
chars = list(set(chars))
chars.sort()
chars = sorted(set(chars))
ans = OrderedDict()
for i, glyph_id in enumerate(self.bmp_table.get_glyph_ids(chars)):
if glyph_id > 0:
@ -230,8 +229,7 @@ class CmapTable(UnknownTable):
def set_character_map(self, cmap):
self.version, self.num_tables = 0, 1
fmt = b'>7H'
codes = list(iterkeys(cmap))
codes.sort()
codes = sorted(iterkeys(cmap))
if not codes:
start_code = [0xffff]

View File

@ -167,6 +167,7 @@ def test_roundtrip(ff=None):
raise ValueError('Roundtripping failed, size different (%d vs. %d)'%
(len(data), len(rd)))
if __name__ == '__main__':
import sys
test_roundtrip(sys.argv[-1])

View File

@ -132,6 +132,7 @@ class ReverseChainSingleSubstitution(UnknownLookupSubTable):
gid_index_map = self.coverage.coverage_indices(glyph_ids)
return {self.substitutes[i] for i in itervalues(gid_index_map)}
subtable_map = {
1: SingleSubstitution,
2: MultipleSubstitution,

View File

@ -176,5 +176,6 @@ def test():
prints(' ', font, data[0], data[1], len(data[2]))
print()
if __name__ == '__main__':
test()

View File

@ -316,5 +316,6 @@ class LocalZipFile(object):
shutil.copyfileobj(temp, zipstream)
zipstream.flush()
if __name__ == '__main__':
extractall(sys.argv[-1])

View File

@ -39,4 +39,6 @@ def points_for_word(w):
ans = plugins['unicode_names'][0].codepoints_for_word(w.encode('utf-8')) | html_entities().get(w, set())
points_for_word.cache[w] = ans
return ans
points_for_word.cache = {} # noqa

View File

@ -27,6 +27,7 @@ xpath_cache = OrderedDict()
# Test that the string is not empty and does not contain whitespace
is_non_whitespace = re.compile(r'^[^ \t\r\n\f]+$').match
def get_parsed_selector(raw):
try:
return parse_cache[raw]
@ -36,6 +37,7 @@ def get_parsed_selector(raw):
parse_cache.pop(next(iter(parse_cache)))
return ans
def get_compiled_xpath(expr):
try:
return xpath_cache[expr]
@ -45,12 +47,16 @@ def get_compiled_xpath(expr):
xpath_cache.pop(next(iter(xpath_cache)))
return ans
class AlwaysIn(object):
def __contains__(self, x):
return True
always_in = AlwaysIn()
def trace_wrapper(func):
@wraps(func)
def trace(*args, **kwargs):
@ -59,6 +65,7 @@ def trace_wrapper(func):
return func(*args, **kwargs)
return trace
def normalize_language_tag(tag):
"""Return a list of normalized combinations for a `BCP 47` language tag.
@ -80,9 +87,11 @@ def normalize_language_tag(tag):
taglist.add('-'.join(base_tag + tags))
return taglist
INAPPROPRIATE_PSEUDO_CLASSES = frozenset([
'active', 'after', 'disabled', 'visited', 'link', 'before', 'focus', 'first-letter', 'enabled', 'first-line', 'hover', 'checked', 'target'])
class Select(object):
'''
@ -325,6 +334,7 @@ class Select(object):
# Combinators {{{
def select_combinedselector(cache, combined):
"""Translate a combined selector."""
combinator = cache.combinator_mapping[combined.combinator]
@ -334,6 +344,7 @@ def select_combinedselector(cache, combined):
for item in cache.dispatch_map[combinator](cache, cache.iterparsedselector(combined.selector), right):
yield item
def select_descendant(cache, left, right):
"""right is a child, grand-child or further descendant of left"""
right = always_in if right is None else frozenset(right)
@ -342,6 +353,7 @@ def select_descendant(cache, left, right):
if descendant in right:
yield descendant
def select_child(cache, left, right):
"""right is an immediate child of left"""
right = always_in if right is None else frozenset(right)
@ -350,6 +362,7 @@ def select_child(cache, left, right):
if child in right:
yield child
def select_direct_adjacent(cache, left, right):
"""right is a sibling immediately after left"""
right = always_in if right is None else frozenset(right)
@ -359,6 +372,7 @@ def select_direct_adjacent(cache, left, right):
yield sibling
break
def select_indirect_adjacent(cache, left, right):
"""right is a sibling after left, immediately or not"""
right = always_in if right is None else frozenset(right)
@ -368,6 +382,7 @@ def select_indirect_adjacent(cache, left, right):
yield sibling
# }}}
def select_element(cache, selector):
"""A type or universal selector."""
element = selector.element
@ -378,6 +393,7 @@ def select_element(cache, selector):
for elem in cache.element_map[ascii_lower(element)]:
yield elem
def select_hash(cache, selector):
'An id selector'
items = cache.id_map[ascii_lower(selector.id)]
@ -386,6 +402,7 @@ def select_hash(cache, selector):
if elem in items:
yield elem
def select_class(cache, selector):
'A class selector'
items = cache.class_map[ascii_lower(selector.class_name)]
@ -394,6 +411,7 @@ def select_class(cache, selector):
if elem in items:
yield elem
def select_negation(cache, selector):
'Implement :not()'
exclude = frozenset(cache.iterparsedselector(selector.subselector))
@ -403,6 +421,7 @@ def select_negation(cache, selector):
# Attribute selectors {{{
def select_attrib(cache, selector):
operator = cache.attribute_operator_mapping[selector.operator]
items = frozenset(cache.dispatch_map[operator](cache, ascii_lower(selector.attrib), selector.value))
@ -410,20 +429,24 @@ def select_attrib(cache, selector):
if item in items:
yield item
def select_exists(cache, attrib, value=None):
for elem_set in itervalues(cache.attrib_map[attrib]):
for elem in elem_set:
yield elem
def select_equals(cache, attrib, value):
for elem in cache.attrib_map[attrib][value]:
yield elem
def select_includes(cache, attrib, value):
if is_non_whitespace(value):
for elem in cache.attrib_space_map[attrib][value]:
yield elem
def select_dashmatch(cache, attrib, value):
if value:
for val, elem_set in iteritems(cache.attrib_map[attrib]):
@ -431,6 +454,7 @@ def select_dashmatch(cache, attrib, value):
for elem in elem_set:
yield elem
def select_prefixmatch(cache, attrib, value):
if value:
for val, elem_set in iteritems(cache.attrib_map[attrib]):
@ -438,6 +462,7 @@ def select_prefixmatch(cache, attrib, value):
for elem in elem_set:
yield elem
def select_suffixmatch(cache, attrib, value):
if value:
for val, elem_set in iteritems(cache.attrib_map[attrib]):
@ -445,6 +470,7 @@ def select_suffixmatch(cache, attrib, value):
for elem in elem_set:
yield elem
def select_substringmatch(cache, attrib, value):
if value:
for val, elem_set in iteritems(cache.attrib_map[attrib]):
@ -456,6 +482,7 @@ def select_substringmatch(cache, attrib, value):
# Function selectors {{{
def select_function(cache, function):
"""Select with a functional pseudo-class."""
fname = function.name.replace('-', '_')
@ -474,6 +501,7 @@ def select_function(cache, function):
if func(cache, function, item):
yield item
def select_lang(cache, function):
' Implement :lang() '
if function.argument_types() not in (['STRING'], ['IDENT']):
@ -487,6 +515,7 @@ def select_lang(cache, function):
for elem in elem_set:
yield elem
def select_nth_child(cache, function, elem):
' Implement :nth-child() '
a, b = function.parsed_arguments
@ -499,6 +528,7 @@ def select_nth_child(cache, function, elem):
n = (num - b) / a
return n.is_integer() and n > -1
def select_nth_last_child(cache, function, elem):
' Implement :nth-last-child() '
a, b = function.parsed_arguments
@ -511,6 +541,7 @@ def select_nth_last_child(cache, function, elem):
n = (num - b) / a
return n.is_integer() and n > -1
def select_nth_of_type(cache, function, elem):
' Implement :nth-of-type() '
a, b = function.parsed_arguments
@ -523,6 +554,7 @@ def select_nth_of_type(cache, function, elem):
n = (num - b) / a
return n.is_integer() and n > -1
def select_nth_last_of_type(cache, function, elem):
' Implement :nth-last-of-type() '
a, b = function.parsed_arguments
@ -539,6 +571,7 @@ def select_nth_last_of_type(cache, function, elem):
# Pseudo elements {{{
def select_pseudo(cache, pseudo):
try:
func = cache.dispatch_map[pseudo.ident.replace('-', '_')]
@ -565,50 +598,71 @@ def select_pseudo(cache, pseudo):
if func(cache, item):
yield item
def select_first_child(cache, elem):
try:
return cache.sibling_count(elem) == 0
except ValueError:
return False
select_first_child.is_pseudo = True
def select_last_child(cache, elem):
try:
return cache.sibling_count(elem, before=False) == 0
except ValueError:
return False
select_last_child.is_pseudo = True
def select_only_child(cache, elem):
try:
return cache.all_sibling_count(elem) == 0
except ValueError:
return False
select_only_child.is_pseudo = True
def select_first_of_type(cache, elem):
try:
return cache.sibling_count(elem, same_type=True) == 0
except ValueError:
return False
select_first_of_type.is_pseudo = True
def select_last_of_type(cache, elem):
try:
return cache.sibling_count(elem, before=False, same_type=True) == 0
except ValueError:
return False
select_last_of_type.is_pseudo = True
def select_only_of_type(cache, elem):
try:
return cache.all_sibling_count(elem, same_type=True) == 0
except ValueError:
return False
select_only_of_type.is_pseudo = True
def select_empty(cache, elem):
return cache.is_empty(elem)
select_empty.is_pseudo = True
# }}}

View File

@ -47,6 +47,7 @@ def make_parser(*features, **kwargs):
parser_class = CSS21Parser
return parser_class(**kwargs)
def make_full_parser(**kwargs):
''' A parser that parses all supported CSS 3 modules in addition to CSS 2.1 '''
features = tuple(iterkeys(PARSER_MODULES))

View File

@ -11,6 +11,7 @@ from tinycss.tests import BaseTest
from polyglot.builtins import iteritems
class TestFonts3(BaseTest):
def test_font_face(self):