eric6/ThirdParty/Pygments/pygments/util.py

changeset 7547
21b0534faebc
parent 6942
2602857055c5
child 7701
25f42e208e08
equal deleted inserted replaced
7546:bf5f777260a6 7547:21b0534faebc
3 pygments.util 3 pygments.util
4 ~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~
5 5
6 Utility functions. 6 Utility functions.
7 7
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS. 8 :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details. 9 :license: BSD, see LICENSE for details.
10 """ 10 """
11 11
12 import re 12 import re
13 import sys 13 import sys
14 from io import TextIOWrapper
14 15
15 16
16 split_path_re = re.compile(r'[/\\ ]') 17 split_path_re = re.compile(r'[/\\ ]')
17 doctype_lookup_re = re.compile(r''' 18 doctype_lookup_re = re.compile(r'''
18 (<\?.*?\?>)?\s* 19 (<\?.*?\?>)?\s*
51 string = options.get(optname, default) 52 string = options.get(optname, default)
52 if isinstance(string, bool): 53 if isinstance(string, bool):
53 return string 54 return string
54 elif isinstance(string, int): 55 elif isinstance(string, int):
55 return bool(string) 56 return bool(string)
56 elif not isinstance(string, string_types): 57 elif not isinstance(string, str):
57 raise OptionError('Invalid type %r for option %s; use ' 58 raise OptionError('Invalid type %r for option %s; use '
58 '1/0, yes/no, true/false, on/off' % ( 59 '1/0, yes/no, true/false, on/off' % (
59 string, optname)) 60 string, optname))
60 elif string.lower() in ('1', 'yes', 'true', 'on'): 61 elif string.lower() in ('1', 'yes', 'true', 'on'):
61 return True 62 return True
81 string, optname)) 82 string, optname))
82 83
83 84
84 def get_list_opt(options, optname, default=None): 85 def get_list_opt(options, optname, default=None):
85 val = options.get(optname, default) 86 val = options.get(optname, default)
86 if isinstance(val, string_types): 87 if isinstance(val, str):
87 return val.split() 88 return val.split()
88 elif isinstance(val, (list, tuple)): 89 elif isinstance(val, (list, tuple)):
89 return list(val) 90 return list(val)
90 else: 91 else:
91 raise OptionError('Invalid type %r for option %s; you ' 92 raise OptionError('Invalid type %r for option %s; you '
171 """Check if the doctype matches a regular expression (if present). 172 """Check if the doctype matches a regular expression (if present).
172 173
173 Note that this method only checks the first part of a DOCTYPE. 174 Note that this method only checks the first part of a DOCTYPE.
174 eg: 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' 175 eg: 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
175 """ 176 """
176 m = doctype_lookup_re.match(text) 177 m = doctype_lookup_re.search(text)
177 if m is None: 178 if m is None:
178 return False 179 return False
179 doctype = m.group(2) 180 doctype = m.group(2)
180 return re.compile(regex, re.I).match(doctype.strip()) is not None 181 return re.compile(regex, re.I).match(doctype.strip()) is not None
181 182
194 return True 195 return True
195 key = hash(text) 196 key = hash(text)
196 try: 197 try:
197 return _looks_like_xml_cache[key] 198 return _looks_like_xml_cache[key]
198 except KeyError: 199 except KeyError:
199 m = doctype_lookup_re.match(text) 200 m = doctype_lookup_re.search(text)
200 if m is not None: 201 if m is not None:
201 return True 202 return True
202 rv = tag_re.search(text[:1000]) is not None 203 rv = tag_re.search(text[:1000]) is not None
203 _looks_like_xml_cache[key] = rv 204 _looks_like_xml_cache[key] = rv
204 return rv 205 return rv
222 if a < 0x10000 or b < 0x10000: 223 if a < 0x10000 or b < 0x10000:
223 raise ValueError("unirange is only defined for non-BMP ranges") 224 raise ValueError("unirange is only defined for non-BMP ranges")
224 225
225 if sys.maxunicode > 0xffff: 226 if sys.maxunicode > 0xffff:
226 # wide build 227 # wide build
227 return u'[%s-%s]' % (unichr(a), unichr(b)) 228 return u'[%s-%s]' % (chr(a), chr(b))
228 else: 229 else:
229 # narrow build stores surrogates, and the 're' module handles them 230 # narrow build stores surrogates, and the 're' module handles them
230 # (incorrectly) as characters. Since there is still ordering among 231 # (incorrectly) as characters. Since there is still ordering among
231 # these characters, expand the range to one that it understands. Some 232 # these characters, expand the range to one that it understands. Some
232 # background in http://bugs.python.org/issue3665 and 233 # background in http://bugs.python.org/issue3665 and
233 # http://bugs.python.org/issue12749 234 # http://bugs.python.org/issue12749
234 # 235 #
235 # Additionally, the lower constants are using unichr rather than 236 # Additionally, the lower constants are using chr rather than
236 # literals because jython [which uses the wide path] can't load this 237 # literals because jython [which uses the wide path] can't load this
237 # file if they are literals. 238 # file if they are literals.
238 ah, al = _surrogatepair(a) 239 ah, al = _surrogatepair(a)
239 bh, bl = _surrogatepair(b) 240 bh, bl = _surrogatepair(b)
240 if ah == bh: 241 if ah == bh:
241 return u'(?:%s[%s-%s])' % (unichr(ah), unichr(al), unichr(bl)) 242 return u'(?:%s[%s-%s])' % (chr(ah), chr(al), chr(bl))
242 else: 243 else:
243 buf = [] 244 buf = []
244 buf.append(u'%s[%s-%s]' % 245 buf.append(u'%s[%s-%s]' % (chr(ah), chr(al),
245 (unichr(ah), unichr(al), 246 ah == bh and chr(bl) or chr(0xdfff)))
246 ah == bh and unichr(bl) or unichr(0xdfff)))
247 if ah - bh > 1: 247 if ah - bh > 1:
248 buf.append(u'[%s-%s][%s-%s]' % 248 buf.append(u'[%s-%s][%s-%s]' %
249 unichr(ah+1), unichr(bh-1), unichr(0xdc00), unichr(0xdfff)) 249 chr(ah+1), chr(bh-1), chr(0xdc00), chr(0xdfff))
250 if ah != bh: 250 if ah != bh:
251 buf.append(u'%s[%s-%s]' % 251 buf.append(u'%s[%s-%s]' %
252 (unichr(bh), unichr(0xdc00), unichr(bl))) 252 (chr(bh), chr(0xdc00), chr(bl)))
253 253
254 return u'(?:' + u'|'.join(buf) + u')' 254 return u'(?:' + u'|'.join(buf) + u')'
255 255
256 256
257 def format_lines(var_name, seq, raw=False, indent_level=0): 257 def format_lines(var_name, seq, raw=False, indent_level=0):
287 lst.append(i) 287 lst.append(i)
288 seen.add(i) 288 seen.add(i)
289 return lst 289 return lst
290 290
291 291
292 class Future(object): 292 class Future:
293 """Generic class to defer some work. 293 """Generic class to defer some work.
294 294
295 Handled specially in RegexLexerMeta, to support regex string construction at 295 Handled specially in RegexLexerMeta, to support regex string construction at
296 first use. 296 first use.
297 """ 297 """
343 return term.encoding 343 return term.encoding
344 import locale 344 import locale
345 return locale.getpreferredencoding() 345 return locale.getpreferredencoding()
346 346
347 347
348 # Python 2/3 compatibility 348 class UnclosingTextIOWrapper(TextIOWrapper):
349 349 # Don't close underlying buffer on destruction.
350 if sys.version_info < (3, 0): 350 def close(self):
351 unichr = unichr 351 self.flush()
352 xrange = xrange
353 string_types = (str, unicode)
354 text_type = unicode
355 u_prefix = 'u'
356 iteritems = dict.iteritems
357 itervalues = dict.itervalues
358 import StringIO
359 import cStringIO
360 # unfortunately, io.StringIO in Python 2 doesn't accept str at all
361 StringIO = StringIO.StringIO
362 BytesIO = cStringIO.StringIO
363 else:
364 unichr = chr
365 xrange = range
366 string_types = (str,)
367 text_type = str
368 u_prefix = ''
369 iteritems = dict.items
370 itervalues = dict.values
371 from io import StringIO, BytesIO, TextIOWrapper
372
373 class UnclosingTextIOWrapper(TextIOWrapper):
374 # Don't close underlying buffer on destruction.
375 def close(self):
376 self.flush()
377
378
379 def add_metaclass(metaclass):
380 """Class decorator for creating a class with a metaclass."""
381 def wrapper(cls):
382 orig_vars = cls.__dict__.copy()
383 orig_vars.pop('__dict__', None)
384 orig_vars.pop('__weakref__', None)
385 for slots_var in orig_vars.get('__slots__', ()):
386 orig_vars.pop(slots_var)
387 return metaclass(cls.__name__, cls.__bases__, orig_vars)
388 return wrapper

eric ide

mercurial