1# -*- coding: utf-8 -*- 2# 3# Copyright © Spyder Project Contributors 4# Licensed under the terms of the MIT License 5# (see spyder/__init__.py for details) 6 7""" 8Editor widget syntax highlighters based on QtGui.QSyntaxHighlighter 9(Python syntax highlighting rules are inspired from idlelib) 10""" 11 12# Standard library imports 13from __future__ import print_function 14import keyword 15import os 16import re 17 18# Third party imports 19from qtpy.QtCore import Qt 20from qtpy.QtGui import (QColor, QCursor, QFont, QSyntaxHighlighter, 21 QTextCharFormat, QTextOption) 22from qtpy.QtWidgets import QApplication 23 24# Local imports 25from spyder import dependencies 26from spyder.config.base import _ 27from spyder.config.main import CONF 28from spyder.py3compat import builtins, is_text_string, to_text_string 29from spyder.utils.sourcecode import CELL_LANGUAGES 30from spyder.utils.workers import WorkerManager 31 32 33PYGMENTS_REQVER = '>=2.0' 34dependencies.add("pygments", _("Syntax highlighting for Matlab, Julia and " 35 "other file types"), 36 required_version=PYGMENTS_REQVER) 37 38 39# ============================================================================= 40# Constants 41# ============================================================================= 42COLOR_SCHEME_KEYS = { 43 "background": _("Background:"), 44 "currentline": _("Current line:"), 45 "currentcell": _("Current cell:"), 46 "occurrence": _("Occurrence:"), 47 "ctrlclick": _("Link:"), 48 "sideareas": _("Side areas:"), 49 "matched_p": _("Matched <br>parens:"), 50 "unmatched_p": _("Unmatched <br>parens:"), 51 "normal": _("Normal text:"), 52 "keyword": _("Keyword:"), 53 "builtin": _("Builtin:"), 54 "definition": _("Definition:"), 55 "comment": _("Comment:"), 56 "string": _("String:"), 57 "number": _("Number:"), 58 "instance": _("Instance:"), 59 } 60COLOR_SCHEME_NAMES = CONF.get('color_schemes', 'names') 61# Mapping for file extensions that use Pygments highlighting but should use 62# different lexers than Pygments' autodetection suggests. Keys are file 63# extensions or tuples of extensions, values are Pygments lexer names. 64CUSTOM_EXTENSION_LEXER = {'.ipynb': 'json', 65 '.txt': 'text', 66 '.nt': 'bat', 67 '.m': 'matlab', 68 ('.properties', '.session', '.inf', '.reg', '.url', 69 '.cfg', '.cnf', '.aut', '.iss'): 'ini'} 70# Convert custom extensions into a one-to-one mapping for easier lookup. 71custom_extension_lexer_mapping = {} 72for key, value in CUSTOM_EXTENSION_LEXER.items(): 73 # Single key is mapped unchanged. 74 if is_text_string(key): 75 custom_extension_lexer_mapping[key] = value 76 # Tuple of keys is iterated over and each is mapped to value. 77 else: 78 for k in key: 79 custom_extension_lexer_mapping[k] = value 80 81 82#============================================================================== 83# Auxiliary functions 84#============================================================================== 85def get_color_scheme(name): 86 """Get a color scheme from config using its name""" 87 name = name.lower() 88 scheme = {} 89 for key in COLOR_SCHEME_KEYS: 90 try: 91 scheme[key] = CONF.get('color_schemes', name+'/'+key) 92 except: 93 scheme[key] = CONF.get('color_schemes', 'spyder/'+key) 94 return scheme 95 96 97#============================================================================== 98# Syntax highlighting color schemes 99#============================================================================== 100class BaseSH(QSyntaxHighlighter): 101 """Base Syntax Highlighter Class""" 102 # Syntax highlighting rules: 103 PROG = None 104 BLANKPROG = re.compile(r"\s+") 105 # Syntax highlighting states (from one text block to another): 106 NORMAL = 0 107 # Syntax highlighting parameters. 108 BLANK_ALPHA_FACTOR = 0.31 109 110 def __init__(self, parent, font=None, color_scheme='Spyder'): 111 QSyntaxHighlighter.__init__(self, parent) 112 113 self.outlineexplorer_data = {} 114 115 self.font = font 116 if is_text_string(color_scheme): 117 self.color_scheme = get_color_scheme(color_scheme) 118 else: 119 self.color_scheme = color_scheme 120 121 self.background_color = None 122 self.currentline_color = None 123 self.currentcell_color = None 124 self.occurrence_color = None 125 self.ctrlclick_color = None 126 self.sideareas_color = None 127 self.matched_p_color = None 128 self.unmatched_p_color = None 129 130 self.formats = None 131 self.setup_formats(font) 132 133 self.cell_separators = None 134 135 def get_background_color(self): 136 return QColor(self.background_color) 137 138 def get_foreground_color(self): 139 """Return foreground ('normal' text) color""" 140 return self.formats["normal"].foreground().color() 141 142 def get_currentline_color(self): 143 return QColor(self.currentline_color) 144 145 def get_currentcell_color(self): 146 return QColor(self.currentcell_color) 147 148 def get_occurrence_color(self): 149 return QColor(self.occurrence_color) 150 151 def get_ctrlclick_color(self): 152 return QColor(self.ctrlclick_color) 153 154 def get_sideareas_color(self): 155 return QColor(self.sideareas_color) 156 157 def get_matched_p_color(self): 158 return QColor(self.matched_p_color) 159 160 def get_unmatched_p_color(self): 161 return QColor(self.unmatched_p_color) 162 163 def get_comment_color(self): 164 """ Return color for the comments """ 165 return self.formats['comment'].foreground().color() 166 167 def get_color_name(self, fmt): 168 """Return color name assigned to a given format""" 169 return self.formats[fmt].foreground().color().name() 170 171 def setup_formats(self, font=None): 172 base_format = QTextCharFormat() 173 if font is not None: 174 self.font = font 175 if self.font is not None: 176 base_format.setFont(self.font) 177 self.formats = {} 178 colors = self.color_scheme.copy() 179 self.background_color = colors.pop("background") 180 self.currentline_color = colors.pop("currentline") 181 self.currentcell_color = colors.pop("currentcell") 182 self.occurrence_color = colors.pop("occurrence") 183 self.ctrlclick_color = colors.pop("ctrlclick") 184 self.sideareas_color = colors.pop("sideareas") 185 self.matched_p_color = colors.pop("matched_p") 186 self.unmatched_p_color = colors.pop("unmatched_p") 187 for name, (color, bold, italic) in list(colors.items()): 188 format = QTextCharFormat(base_format) 189 format.setForeground(QColor(color)) 190 format.setBackground(QColor(self.background_color)) 191 if bold: 192 format.setFontWeight(QFont.Bold) 193 format.setFontItalic(italic) 194 self.formats[name] = format 195 196 def set_color_scheme(self, color_scheme): 197 if is_text_string(color_scheme): 198 self.color_scheme = get_color_scheme(color_scheme) 199 else: 200 self.color_scheme = color_scheme 201 self.setup_formats() 202 self.rehighlight() 203 204 def highlightBlock(self, text): 205 raise NotImplementedError 206 207 def highlight_spaces(self, text, offset=0): 208 """ 209 Make blank space less apparent by setting the foreground alpha. 210 This only has an effect when 'Show blank space' is turned on. 211 Derived classes could call this function at the end of 212 highlightBlock(). 213 """ 214 flags_text = self.document().defaultTextOption().flags() 215 show_blanks = flags_text & QTextOption.ShowTabsAndSpaces 216 if show_blanks: 217 format_leading = self.formats.get("leading", None) 218 format_trailing = self.formats.get("trailing", None) 219 match = self.BLANKPROG.search(text, offset) 220 while match: 221 start, end = match.span() 222 start = max([0, start+offset]) 223 end = max([0, end+offset]) 224 # Format trailing spaces at the end of the line. 225 if end == len(text) and format_trailing is not None: 226 self.setFormat(start, end, format_trailing) 227 # Format leading spaces, e.g. indentation. 228 if start == 0 and format_leading is not None: 229 self.setFormat(start, end, format_leading) 230 format = self.format(start) 231 color_foreground = format.foreground().color() 232 alpha_new = self.BLANK_ALPHA_FACTOR * color_foreground.alphaF() 233 color_foreground.setAlphaF(alpha_new) 234 self.setFormat(start, end-start, color_foreground) 235 match = self.BLANKPROG.search(text, match.end()) 236 237 def get_outlineexplorer_data(self): 238 return self.outlineexplorer_data 239 240 def rehighlight(self): 241 self.outlineexplorer_data = {} 242 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 243 QSyntaxHighlighter.rehighlight(self) 244 QApplication.restoreOverrideCursor() 245 246 247class TextSH(BaseSH): 248 """Simple Text Syntax Highlighter Class (only highlight spaces)""" 249 def highlightBlock(self, text): 250 self.highlight_spaces(text) 251 252 253class GenericSH(BaseSH): 254 """Generic Syntax Highlighter""" 255 # Syntax highlighting rules: 256 PROG = None # to be redefined in child classes 257 def highlightBlock(self, text): 258 text = to_text_string(text) 259 self.setFormat(0, len(text), self.formats["normal"]) 260 261 match = self.PROG.search(text) 262 index = 0 263 while match: 264 for key, value in list(match.groupdict().items()): 265 if value: 266 start, end = match.span(key) 267 index += end-start 268 self.setFormat(start, end-start, self.formats[key]) 269 270 match = self.PROG.search(text, match.end()) 271 272 self.highlight_spaces(text) 273 274 275#============================================================================== 276# Python syntax highlighter 277#============================================================================== 278def any(name, alternates): 279 "Return a named group pattern matching list of alternates." 280 return "(?P<%s>" % name + "|".join(alternates) + ")" 281 282def make_python_patterns(additional_keywords=[], additional_builtins=[]): 283 "Strongly inspired from idlelib.ColorDelegator.make_pat" 284 kwlist = keyword.kwlist + additional_keywords 285 builtinlist = [str(name) for name in dir(builtins) 286 if not name.startswith('_')] + additional_builtins 287 repeated = set(kwlist) & set(builtinlist) 288 for repeated_element in repeated: 289 kwlist.remove(repeated_element) 290 kw = r"\b" + any("keyword", kwlist) + r"\b" 291 builtin = r"([^.'\"\\#]\b|^)" + any("builtin", builtinlist) + r"\b" 292 comment = any("comment", [r"#[^\n]*"]) 293 instance = any("instance", [r"\bself\b", 294 (r"^\s*@([a-zA-Z_][a-zA-Z0-9_]*)" 295 r"(\.[a-zA-Z_][a-zA-Z0-9_]*)*")]) 296 number = any("number", 297 [r"\b[+-]?[0-9]+[lLjJ]?\b", 298 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 299 r"\b[+-]?0[oO][0-7]+[lL]?\b", 300 r"\b[+-]?0[bB][01]+[lL]?\b", 301 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?[jJ]?\b"]) 302 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 303 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 304 uf_sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*(\\)$(?!')$" 305 uf_dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*(\\)$(?!")$' 306 sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" 307 dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' 308 uf_sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(\\)?(?!''')$" 309 uf_dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(\\)?(?!""")$' 310 string = any("string", [sq3string, dq3string, sqstring, dqstring]) 311 ufstring1 = any("uf_sqstring", [uf_sqstring]) 312 ufstring2 = any("uf_dqstring", [uf_dqstring]) 313 ufstring3 = any("uf_sq3string", [uf_sq3string]) 314 ufstring4 = any("uf_dq3string", [uf_dq3string]) 315 return "|".join([instance, kw, builtin, comment, 316 ufstring1, ufstring2, ufstring3, ufstring4, string, 317 number, any("SYNC", [r"\n"])]) 318 319class OutlineExplorerData(object): 320 CLASS, FUNCTION, STATEMENT, COMMENT, CELL = list(range(5)) 321 FUNCTION_TOKEN = 'def' 322 CLASS_TOKEN = 'class' 323 324 def __init__(self): 325 self.text = None 326 self.fold_level = None 327 self.def_type = None 328 self.def_name = None 329 330 def is_not_class_nor_function(self): 331 return self.def_type not in (self.CLASS, self.FUNCTION) 332 333 def is_class_or_function(self): 334 return self.def_type in (self.CLASS, self.FUNCTION) 335 336 def is_comment(self): 337 return self.def_type in (self.COMMENT, self.CELL) 338 339 def get_class_name(self): 340 if self.def_type == self.CLASS: 341 return self.def_name 342 343 def get_function_name(self): 344 if self.def_type == self.FUNCTION: 345 return self.def_name 346 347 def get_token(self): 348 if self.def_type == self.FUNCTION: 349 token = self.FUNCTION_TOKEN 350 elif self.def_type == self.CLASS: 351 token = self.CLASS_TOKEN 352 353 return token 354 355 356class PythonSH(BaseSH): 357 """Python Syntax Highlighter""" 358 # Syntax highlighting rules: 359 add_kw = ['async', 'await'] 360 PROG = re.compile(make_python_patterns(additional_keywords=add_kw), re.S) 361 IDPROG = re.compile(r"\s+(\w+)", re.S) 362 ASPROG = re.compile(r".*?\b(as)\b") 363 # Syntax highlighting states (from one text block to another): 364 (NORMAL, INSIDE_SQ3STRING, INSIDE_DQ3STRING, 365 INSIDE_SQSTRING, INSIDE_DQSTRING) = list(range(5)) 366 DEF_TYPES = {"def": OutlineExplorerData.FUNCTION, 367 "class": OutlineExplorerData.CLASS} 368 # Comments suitable for Outline Explorer 369 OECOMMENT = re.compile(r'^(# ?--[-]+|##[#]+ )[ -]*[^- ]+') 370 371 def __init__(self, parent, font=None, color_scheme='Spyder'): 372 BaseSH.__init__(self, parent, font, color_scheme) 373 self.import_statements = {} 374 self.found_cell_separators = False 375 self.cell_separators = CELL_LANGUAGES['Python'] 376 377 def highlightBlock(self, text): 378 text = to_text_string(text) 379 prev_state = self.previousBlockState() 380 if prev_state == self.INSIDE_DQ3STRING: 381 offset = -4 382 text = r'""" '+text 383 elif prev_state == self.INSIDE_SQ3STRING: 384 offset = -4 385 text = r"''' "+text 386 elif prev_state == self.INSIDE_DQSTRING: 387 offset = -2 388 text = r'" '+text 389 elif prev_state == self.INSIDE_SQSTRING: 390 offset = -2 391 text = r"' "+text 392 else: 393 offset = 0 394 prev_state = self.NORMAL 395 396 oedata = None 397 import_stmt = None 398 399 self.setFormat(0, len(text), self.formats["normal"]) 400 401 state = self.NORMAL 402 match = self.PROG.search(text) 403 while match: 404 for key, value in list(match.groupdict().items()): 405 if value: 406 start, end = match.span(key) 407 start = max([0, start+offset]) 408 end = max([0, end+offset]) 409 if key == "uf_sq3string": 410 self.setFormat(start, end-start, 411 self.formats["string"]) 412 state = self.INSIDE_SQ3STRING 413 elif key == "uf_dq3string": 414 self.setFormat(start, end-start, 415 self.formats["string"]) 416 state = self.INSIDE_DQ3STRING 417 elif key == "uf_sqstring": 418 self.setFormat(start, end-start, 419 self.formats["string"]) 420 state = self.INSIDE_SQSTRING 421 elif key == "uf_dqstring": 422 self.setFormat(start, end-start, 423 self.formats["string"]) 424 state = self.INSIDE_DQSTRING 425 else: 426 self.setFormat(start, end-start, self.formats[key]) 427 if key == "comment": 428 if text.lstrip().startswith(self.cell_separators): 429 self.found_cell_separators = True 430 oedata = OutlineExplorerData() 431 oedata.text = to_text_string(text).strip() 432 oedata.fold_level = start 433 oedata.def_type = OutlineExplorerData.CELL 434 oedata.def_name = text.strip() 435 elif self.OECOMMENT.match(text.lstrip()): 436 oedata = OutlineExplorerData() 437 oedata.text = to_text_string(text).strip() 438 oedata.fold_level = start 439 oedata.def_type = OutlineExplorerData.COMMENT 440 oedata.def_name = text.strip() 441 elif key == "keyword": 442 if value in ("def", "class"): 443 match1 = self.IDPROG.match(text, end) 444 if match1: 445 start1, end1 = match1.span(1) 446 self.setFormat(start1, end1-start1, 447 self.formats["definition"]) 448 oedata = OutlineExplorerData() 449 oedata.text = to_text_string(text) 450 oedata.fold_level = start 451 oedata.def_type = self.DEF_TYPES[ 452 to_text_string(value)] 453 oedata.def_name = text[start1:end1] 454 oedata.color = self.formats["definition"] 455 elif value in ("elif", "else", "except", "finally", 456 "for", "if", "try", "while", 457 "with"): 458 if text.lstrip().startswith(value): 459 oedata = OutlineExplorerData() 460 oedata.text = to_text_string(text).strip() 461 oedata.fold_level = start 462 oedata.def_type = \ 463 OutlineExplorerData.STATEMENT 464 oedata.def_name = text.strip() 465 elif value == "import": 466 import_stmt = text.strip() 467 # color all the "as" words on same line, except 468 # if in a comment; cheap approximation to the 469 # truth 470 if '#' in text: 471 endpos = text.index('#') 472 else: 473 endpos = len(text) 474 while True: 475 match1 = self.ASPROG.match(text, end, 476 endpos) 477 if not match1: 478 break 479 start, end = match1.span(1) 480 self.setFormat(start, end-start, 481 self.formats["keyword"]) 482 483 match = self.PROG.search(text, match.end()) 484 485 self.setCurrentBlockState(state) 486 487 # Use normal format for indentation and trailing spaces. 488 self.formats['leading'] = self.formats['normal'] 489 self.formats['trailing'] = self.formats['normal'] 490 self.highlight_spaces(text, offset) 491 492 if oedata is not None: 493 block_nb = self.currentBlock().blockNumber() 494 self.outlineexplorer_data[block_nb] = oedata 495 self.outlineexplorer_data['found_cell_separators'] = self.found_cell_separators 496 if import_stmt is not None: 497 block_nb = self.currentBlock().blockNumber() 498 self.import_statements[block_nb] = import_stmt 499 500 def get_import_statements(self): 501 return list(self.import_statements.values()) 502 503 def rehighlight(self): 504 self.import_statements = {} 505 self.found_cell_separators = False 506 BaseSH.rehighlight(self) 507 508 509#============================================================================== 510# Cython syntax highlighter 511#============================================================================== 512C_TYPES = 'bool char double enum float int long mutable short signed struct unsigned void' 513 514class CythonSH(PythonSH): 515 """Cython Syntax Highlighter""" 516 ADDITIONAL_KEYWORDS = [ 517 "cdef", "ctypedef", "cpdef", "inline", "cimport", "extern", 518 "include", "begin", "end", "by", "gil", "nogil", "const", "public", 519 "readonly", "fused", "static", "api", "DEF", "IF", "ELIF", "ELSE"] 520 521 ADDITIONAL_BUILTINS = C_TYPES.split() + [ 522 "array", "bint", "Py_ssize_t", "intern", "reload", "sizeof", "NULL"] 523 PROG = re.compile(make_python_patterns(ADDITIONAL_KEYWORDS, 524 ADDITIONAL_BUILTINS), re.S) 525 IDPROG = re.compile(r"\s+([\w\.]+)", re.S) 526 527 528#============================================================================== 529# Enaml syntax highlighter 530#============================================================================== 531class EnamlSH(PythonSH): 532 """Enaml Syntax Highlighter""" 533 ADDITIONAL_KEYWORDS = ["enamldef", "template", "attr", "event", "const", "alias", 534 "func"] 535 ADDITIONAL_BUILTINS = [] 536 PROG = re.compile(make_python_patterns(ADDITIONAL_KEYWORDS, 537 ADDITIONAL_BUILTINS), re.S) 538 IDPROG = re.compile(r"\s+([\w\.]+)", re.S) 539 540 541#============================================================================== 542# C/C++ syntax highlighter 543#============================================================================== 544C_KEYWORDS1 = 'and and_eq bitand bitor break case catch const const_cast continue default delete do dynamic_cast else explicit export extern for friend goto if inline namespace new not not_eq operator or or_eq private protected public register reinterpret_cast return sizeof static static_cast switch template throw try typedef typeid typename union using virtual while xor xor_eq' 545C_KEYWORDS2 = 'a addindex addtogroup anchor arg attention author b brief bug c class code date def defgroup deprecated dontinclude e em endcode endhtmlonly ifdef endif endlatexonly endlink endverbatim enum example exception f$ file fn hideinitializer htmlinclude htmlonly if image include ingroup internal invariant interface latexonly li line link mainpage name namespace nosubgrouping note overload p page par param post pre ref relates remarks return retval sa section see showinitializer since skip skipline subsection test throw todo typedef union until var verbatim verbinclude version warning weakgroup' 546C_KEYWORDS3 = 'asm auto class compl false true volatile wchar_t' 547 548def make_generic_c_patterns(keywords, builtins, 549 instance=None, define=None, comment=None): 550 "Strongly inspired from idlelib.ColorDelegator.make_pat" 551 kw = r"\b" + any("keyword", keywords.split()) + r"\b" 552 builtin = r"\b" + any("builtin", builtins.split()+C_TYPES.split()) + r"\b" 553 if comment is None: 554 comment = any("comment", [r"//[^\n]*", r"\/\*(.*?)\*\/"]) 555 comment_start = any("comment_start", [r"\/\*"]) 556 comment_end = any("comment_end", [r"\*\/"]) 557 if instance is None: 558 instance = any("instance", [r"\bthis\b"]) 559 number = any("number", 560 [r"\b[+-]?[0-9]+[lL]?\b", 561 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 562 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"]) 563 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 564 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 565 string = any("string", [sqstring, dqstring]) 566 if define is None: 567 define = any("define", [r"#[^\n]*"]) 568 return "|".join([instance, kw, comment, string, number, 569 comment_start, comment_end, builtin, 570 define, any("SYNC", [r"\n"])]) 571 572def make_cpp_patterns(): 573 return make_generic_c_patterns(C_KEYWORDS1+' '+C_KEYWORDS2, C_KEYWORDS3) 574 575class CppSH(BaseSH): 576 """C/C++ Syntax Highlighter""" 577 # Syntax highlighting rules: 578 PROG = re.compile(make_cpp_patterns(), re.S) 579 # Syntax highlighting states (from one text block to another): 580 NORMAL = 0 581 INSIDE_COMMENT = 1 582 def __init__(self, parent, font=None, color_scheme=None): 583 BaseSH.__init__(self, parent, font, color_scheme) 584 585 def highlightBlock(self, text): 586 text = to_text_string(text) 587 inside_comment = self.previousBlockState() == self.INSIDE_COMMENT 588 self.setFormat(0, len(text), 589 self.formats["comment" if inside_comment else "normal"]) 590 591 match = self.PROG.search(text) 592 index = 0 593 while match: 594 for key, value in list(match.groupdict().items()): 595 if value: 596 start, end = match.span(key) 597 index += end-start 598 if key == "comment_start": 599 inside_comment = True 600 self.setFormat(start, len(text)-start, 601 self.formats["comment"]) 602 elif key == "comment_end": 603 inside_comment = False 604 self.setFormat(start, end-start, 605 self.formats["comment"]) 606 elif inside_comment: 607 self.setFormat(start, end-start, 608 self.formats["comment"]) 609 elif key == "define": 610 self.setFormat(start, end-start, 611 self.formats["number"]) 612 else: 613 self.setFormat(start, end-start, self.formats[key]) 614 615 match = self.PROG.search(text, match.end()) 616 617 self.highlight_spaces(text) 618 619 last_state = self.INSIDE_COMMENT if inside_comment else self.NORMAL 620 self.setCurrentBlockState(last_state) 621 622 623def make_opencl_patterns(): 624 # Keywords: 625 kwstr1 = 'cl_char cl_uchar cl_short cl_ushort cl_int cl_uint cl_long cl_ulong cl_half cl_float cl_double cl_platform_id cl_device_id cl_context cl_command_queue cl_mem cl_program cl_kernel cl_event cl_sampler cl_bool cl_bitfield cl_device_type cl_platform_info cl_device_info cl_device_address_info cl_device_fp_config cl_device_mem_cache_type cl_device_local_mem_type cl_device_exec_capabilities cl_command_queue_properties cl_context_properties cl_context_info cl_command_queue_info cl_channel_order cl_channel_type cl_mem_flags cl_mem_object_type cl_mem_info cl_image_info cl_addressing_mode cl_filter_mode cl_sampler_info cl_map_flags cl_program_info cl_program_build_info cl_build_status cl_kernel_info cl_kernel_work_group_info cl_event_info cl_command_type cl_profiling_info cl_image_format' 626 # Constants: 627 kwstr2 = 'CL_FALSE, CL_TRUE, CL_PLATFORM_PROFILE, CL_PLATFORM_VERSION, CL_PLATFORM_NAME, CL_PLATFORM_VENDOR, CL_PLATFORM_EXTENSIONS, CL_DEVICE_TYPE_DEFAULT , CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_ACCELERATOR, CL_DEVICE_TYPE_ALL, CL_DEVICE_TYPE, CL_DEVICE_VENDOR_ID, CL_DEVICE_MAX_COMPUTE_UNITS, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, CL_DEVICE_MAX_WORK_GROUP_SIZE, CL_DEVICE_MAX_WORK_ITEM_SIZES, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, CL_DEVICE_MAX_CLOCK_FREQUENCY, CL_DEVICE_ADDRESS_BITS, CL_DEVICE_MAX_READ_IMAGE_ARGS, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, CL_DEVICE_MAX_MEM_ALLOC_SIZE, CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_WIDTH, CL_DEVICE_IMAGE3D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_DEPTH, CL_DEVICE_IMAGE_SUPPORT, CL_DEVICE_MAX_PARAMETER_SIZE, CL_DEVICE_MAX_SAMPLERS, CL_DEVICE_MEM_BASE_ADDR_ALIGN, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, CL_DEVICE_SINGLE_FP_CONFIG, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, CL_DEVICE_GLOBAL_MEM_SIZE, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, CL_DEVICE_MAX_CONSTANT_ARGS, CL_DEVICE_LOCAL_MEM_TYPE, CL_DEVICE_LOCAL_MEM_SIZE, CL_DEVICE_ERROR_CORRECTION_SUPPORT, CL_DEVICE_PROFILING_TIMER_RESOLUTION, CL_DEVICE_ENDIAN_LITTLE, CL_DEVICE_AVAILABLE, CL_DEVICE_COMPILER_AVAILABLE, CL_DEVICE_EXECUTION_CAPABILITIES, CL_DEVICE_QUEUE_PROPERTIES, CL_DEVICE_NAME, CL_DEVICE_VENDOR, CL_DRIVER_VERSION, CL_DEVICE_PROFILE, CL_DEVICE_VERSION, CL_DEVICE_EXTENSIONS, CL_DEVICE_PLATFORM, CL_FP_DENORM, CL_FP_INF_NAN, CL_FP_ROUND_TO_NEAREST, CL_FP_ROUND_TO_ZERO, CL_FP_ROUND_TO_INF, CL_FP_FMA, CL_NONE, CL_READ_ONLY_CACHE, CL_READ_WRITE_CACHE, CL_LOCAL, CL_GLOBAL, CL_EXEC_KERNEL, CL_EXEC_NATIVE_KERNEL, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, CL_QUEUE_PROFILING_ENABLE, CL_CONTEXT_REFERENCE_COUNT, CL_CONTEXT_DEVICES, CL_CONTEXT_PROPERTIES, CL_CONTEXT_PLATFORM, CL_QUEUE_CONTEXT, CL_QUEUE_DEVICE, CL_QUEUE_REFERENCE_COUNT, CL_QUEUE_PROPERTIES, CL_MEM_READ_WRITE, CL_MEM_WRITE_ONLY, CL_MEM_READ_ONLY, CL_MEM_USE_HOST_PTR, CL_MEM_ALLOC_HOST_PTR, CL_MEM_COPY_HOST_PTR, CL_R, CL_A, CL_RG, CL_RA, CL_RGB, CL_RGBA, CL_BGRA, CL_ARGB, CL_INTENSITY, CL_LUMINANCE, CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16, CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT, CL_MEM_OBJECT_BUFFER, CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE3D, CL_MEM_TYPE, CL_MEM_FLAGS, CL_MEM_SIZECL_MEM_HOST_PTR, CL_MEM_HOST_PTR, CL_MEM_MAP_COUNT, CL_MEM_REFERENCE_COUNT, CL_MEM_CONTEXT, CL_IMAGE_FORMAT, CL_IMAGE_ELEMENT_SIZE, CL_IMAGE_ROW_PITCH, CL_IMAGE_SLICE_PITCH, CL_IMAGE_WIDTH, CL_IMAGE_HEIGHT, CL_IMAGE_DEPTH, CL_ADDRESS_NONE, CL_ADDRESS_CLAMP_TO_EDGE, CL_ADDRESS_CLAMP, CL_ADDRESS_REPEAT, CL_FILTER_NEAREST, CL_FILTER_LINEAR, CL_SAMPLER_REFERENCE_COUNT, CL_SAMPLER_CONTEXT, CL_SAMPLER_NORMALIZED_COORDS, CL_SAMPLER_ADDRESSING_MODE, CL_SAMPLER_FILTER_MODE, CL_MAP_READ, CL_MAP_WRITE, CL_PROGRAM_REFERENCE_COUNT, CL_PROGRAM_CONTEXT, CL_PROGRAM_NUM_DEVICES, CL_PROGRAM_DEVICES, CL_PROGRAM_SOURCE, CL_PROGRAM_BINARY_SIZES, CL_PROGRAM_BINARIES, CL_PROGRAM_BUILD_STATUS, CL_PROGRAM_BUILD_OPTIONS, CL_PROGRAM_BUILD_LOG, CL_BUILD_SUCCESS, CL_BUILD_NONE, CL_BUILD_ERROR, CL_BUILD_IN_PROGRESS, CL_KERNEL_FUNCTION_NAME, CL_KERNEL_NUM_ARGS, CL_KERNEL_REFERENCE_COUNT, CL_KERNEL_CONTEXT, CL_KERNEL_PROGRAM, CL_KERNEL_WORK_GROUP_SIZE, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, CL_KERNEL_LOCAL_MEM_SIZE, CL_EVENT_COMMAND_QUEUE, CL_EVENT_COMMAND_TYPE, CL_EVENT_REFERENCE_COUNT, CL_EVENT_COMMAND_EXECUTION_STATUS, CL_COMMAND_NDRANGE_KERNEL, CL_COMMAND_TASK, CL_COMMAND_NATIVE_KERNEL, CL_COMMAND_READ_BUFFER, CL_COMMAND_WRITE_BUFFER, CL_COMMAND_COPY_BUFFER, CL_COMMAND_READ_IMAGE, CL_COMMAND_WRITE_IMAGE, CL_COMMAND_COPY_IMAGE, CL_COMMAND_COPY_IMAGE_TO_BUFFER, CL_COMMAND_COPY_BUFFER_TO_IMAGE, CL_COMMAND_MAP_BUFFER, CL_COMMAND_MAP_IMAGE, CL_COMMAND_UNMAP_MEM_OBJECT, CL_COMMAND_MARKER, CL_COMMAND_ACQUIRE_GL_OBJECTS, CL_COMMAND_RELEASE_GL_OBJECTS, command execution status, CL_COMPLETE, CL_RUNNING, CL_SUBMITTED, CL_QUEUED, CL_PROFILING_COMMAND_QUEUED, CL_PROFILING_COMMAND_SUBMIT, CL_PROFILING_COMMAND_START, CL_PROFILING_COMMAND_END, CL_CHAR_BIT, CL_SCHAR_MAX, CL_SCHAR_MIN, CL_CHAR_MAX, CL_CHAR_MIN, CL_UCHAR_MAX, CL_SHRT_MAX, CL_SHRT_MIN, CL_USHRT_MAX, CL_INT_MAX, CL_INT_MIN, CL_UINT_MAX, CL_LONG_MAX, CL_LONG_MIN, CL_ULONG_MAX, CL_FLT_DIG, CL_FLT_MANT_DIG, CL_FLT_MAX_10_EXP, CL_FLT_MAX_EXP, CL_FLT_MIN_10_EXP, CL_FLT_MIN_EXP, CL_FLT_RADIX, CL_FLT_MAX, CL_FLT_MIN, CL_FLT_EPSILON, CL_DBL_DIG, CL_DBL_MANT_DIG, CL_DBL_MAX_10_EXP, CL_DBL_MAX_EXP, CL_DBL_MIN_10_EXP, CL_DBL_MIN_EXP, CL_DBL_RADIX, CL_DBL_MAX, CL_DBL_MIN, CL_DBL_EPSILON, CL_SUCCESS, CL_DEVICE_NOT_FOUND, CL_DEVICE_NOT_AVAILABLE, CL_COMPILER_NOT_AVAILABLE, CL_MEM_OBJECT_ALLOCATION_FAILURE, CL_OUT_OF_RESOURCES, CL_OUT_OF_HOST_MEMORY, CL_PROFILING_INFO_NOT_AVAILABLE, CL_MEM_COPY_OVERLAP, CL_IMAGE_FORMAT_MISMATCH, CL_IMAGE_FORMAT_NOT_SUPPORTED, CL_BUILD_PROGRAM_FAILURE, CL_MAP_FAILURE, CL_INVALID_VALUE, CL_INVALID_DEVICE_TYPE, CL_INVALID_PLATFORM, CL_INVALID_DEVICE, CL_INVALID_CONTEXT, CL_INVALID_QUEUE_PROPERTIES, CL_INVALID_COMMAND_QUEUE, CL_INVALID_HOST_PTR, CL_INVALID_MEM_OBJECT, CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, CL_INVALID_IMAGE_SIZE, CL_INVALID_SAMPLER, CL_INVALID_BINARY, CL_INVALID_BUILD_OPTIONS, CL_INVALID_PROGRAM, CL_INVALID_PROGRAM_EXECUTABLE, CL_INVALID_KERNEL_NAME, CL_INVALID_KERNEL_DEFINITION, CL_INVALID_KERNEL, CL_INVALID_ARG_INDEX, CL_INVALID_ARG_VALUE, CL_INVALID_ARG_SIZE, CL_INVALID_KERNEL_ARGS, CL_INVALID_WORK_DIMENSION, CL_INVALID_WORK_GROUP_SIZE, CL_INVALID_WORK_ITEM_SIZE, CL_INVALID_GLOBAL_OFFSET, CL_INVALID_EVENT_WAIT_LIST, CL_INVALID_EVENT, CL_INVALID_OPERATION, CL_INVALID_GL_OBJECT, CL_INVALID_BUFFER_SIZE, CL_INVALID_MIP_LEVEL, CL_INVALID_GLOBAL_WORK_SIZE' 628 # Functions: 629 builtins = 'clGetPlatformIDs, clGetPlatformInfo, clGetDeviceIDs, clGetDeviceInfo, clCreateContext, clCreateContextFromType, clReleaseContext, clGetContextInfo, clCreateCommandQueue, clRetainCommandQueue, clReleaseCommandQueue, clGetCommandQueueInfo, clSetCommandQueueProperty, clCreateBuffer, clCreateImage2D, clCreateImage3D, clRetainMemObject, clReleaseMemObject, clGetSupportedImageFormats, clGetMemObjectInfo, clGetImageInfo, clCreateSampler, clRetainSampler, clReleaseSampler, clGetSamplerInfo, clCreateProgramWithSource, clCreateProgramWithBinary, clRetainProgram, clReleaseProgram, clBuildProgram, clUnloadCompiler, clGetProgramInfo, clGetProgramBuildInfo, clCreateKernel, clCreateKernelsInProgram, clRetainKernel, clReleaseKernel, clSetKernelArg, clGetKernelInfo, clGetKernelWorkGroupInfo, clWaitForEvents, clGetEventInfo, clRetainEvent, clReleaseEvent, clGetEventProfilingInfo, clFlush, clFinish, clEnqueueReadBuffer, clEnqueueWriteBuffer, clEnqueueCopyBuffer, clEnqueueReadImage, clEnqueueWriteImage, clEnqueueCopyImage, clEnqueueCopyImageToBuffer, clEnqueueCopyBufferToImage, clEnqueueMapBuffer, clEnqueueMapImage, clEnqueueUnmapMemObject, clEnqueueNDRangeKernel, clEnqueueTask, clEnqueueNativeKernel, clEnqueueMarker, clEnqueueWaitForEvents, clEnqueueBarrier' 630 # Qualifiers: 631 qualifiers = '__global __local __constant __private __kernel' 632 keyword_list = C_KEYWORDS1+' '+C_KEYWORDS2+' '+kwstr1+' '+kwstr2 633 builtin_list = C_KEYWORDS3+' '+builtins+' '+qualifiers 634 return make_generic_c_patterns(keyword_list, builtin_list) 635 636class OpenCLSH(CppSH): 637 """OpenCL Syntax Highlighter""" 638 PROG = re.compile(make_opencl_patterns(), re.S) 639 640 641#============================================================================== 642# Fortran Syntax Highlighter 643#============================================================================== 644 645def make_fortran_patterns(): 646 "Strongly inspired from idlelib.ColorDelegator.make_pat" 647 kwstr = 'access action advance allocatable allocate apostrophe assign assignment associate asynchronous backspace bind blank blockdata call case character class close common complex contains continue cycle data deallocate decimal delim default dimension direct do dowhile double doubleprecision else elseif elsewhere encoding end endassociate endblockdata enddo endfile endforall endfunction endif endinterface endmodule endprogram endselect endsubroutine endtype endwhere entry eor equivalence err errmsg exist exit external file flush fmt forall form format formatted function go goto id if implicit in include inout integer inquire intent interface intrinsic iomsg iolength iostat kind len logical module name named namelist nextrec nml none nullify number only open opened operator optional out pad parameter pass pause pending pointer pos position precision print private program protected public quote read readwrite real rec recl recursive result return rewind save select selectcase selecttype sequential sign size stat status stop stream subroutine target then to type unformatted unit use value volatile wait where while write' 648 bistr1 = 'abs achar acos acosd adjustl adjustr aimag aimax0 aimin0 aint ajmax0 ajmin0 akmax0 akmin0 all allocated alog alog10 amax0 amax1 amin0 amin1 amod anint any asin asind associated atan atan2 atan2d atand bitest bitl bitlr bitrl bjtest bit_size bktest break btest cabs ccos cdabs cdcos cdexp cdlog cdsin cdsqrt ceiling cexp char clog cmplx conjg cos cosd cosh count cpu_time cshift csin csqrt dabs dacos dacosd dasin dasind datan datan2 datan2d datand date date_and_time dble dcmplx dconjg dcos dcosd dcosh dcotan ddim dexp dfloat dflotk dfloti dflotj digits dim dimag dint dlog dlog10 dmax1 dmin1 dmod dnint dot_product dprod dreal dsign dsin dsind dsinh dsqrt dtan dtand dtanh eoshift epsilon errsns exp exponent float floati floatj floatk floor fraction free huge iabs iachar iand ibclr ibits ibset ichar idate idim idint idnint ieor ifix iiabs iiand iibclr iibits iibset iidim iidint iidnnt iieor iifix iint iior iiqint iiqnnt iishft iishftc iisign ilen imax0 imax1 imin0 imin1 imod index inint inot int int1 int2 int4 int8 iqint iqnint ior ishft ishftc isign isnan izext jiand jibclr jibits jibset jidim jidint jidnnt jieor jifix jint jior jiqint jiqnnt jishft jishftc jisign jmax0 jmax1 jmin0 jmin1 jmod jnint jnot jzext kiabs kiand kibclr kibits kibset kidim kidint kidnnt kieor kifix kind kint kior kishft kishftc kisign kmax0 kmax1 kmin0 kmin1 kmod knint knot kzext lbound leadz len len_trim lenlge lge lgt lle llt log log10 logical lshift malloc matmul max max0 max1 maxexponent maxloc maxval merge min min0 min1 minexponent minloc minval mod modulo mvbits nearest nint not nworkers number_of_processors pack popcnt poppar precision present product radix random random_number random_seed range real repeat reshape rrspacing rshift scale scan secnds selected_int_kind selected_real_kind set_exponent shape sign sin sind sinh size sizeof sngl snglq spacing spread sqrt sum system_clock tan tand tanh tiny transfer transpose trim ubound unpack verify' 649 bistr2 = 'cdabs cdcos cdexp cdlog cdsin cdsqrt cotan cotand dcmplx dconjg dcotan dcotand decode dimag dll_export dll_import doublecomplex dreal dvchk encode find flen flush getarg getcharqq getcl getdat getenv gettim hfix ibchng identifier imag int1 int2 int4 intc intrup invalop iostat_msg isha ishc ishl jfix lacfar locking locnear map nargs nbreak ndperr ndpexc offset ovefl peekcharqq precfill prompt qabs qacos qacosd qasin qasind qatan qatand qatan2 qcmplx qconjg qcos qcosd qcosh qdim qexp qext qextd qfloat qimag qlog qlog10 qmax1 qmin1 qmod qreal qsign qsin qsind qsinh qsqrt qtan qtand qtanh ran rand randu rewrite segment setdat settim system timer undfl unlock union val virtual volatile zabs zcos zexp zlog zsin zsqrt' 650 kw = r"\b" + any("keyword", kwstr.split()) + r"\b" 651 builtin = r"\b" + any("builtin", bistr1.split()+bistr2.split()) + r"\b" 652 comment = any("comment", [r"\![^\n]*"]) 653 number = any("number", 654 [r"\b[+-]?[0-9]+[lL]?\b", 655 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 656 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"]) 657 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 658 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 659 string = any("string", [sqstring, dqstring]) 660 return "|".join([kw, comment, string, number, builtin, 661 any("SYNC", [r"\n"])]) 662 663class FortranSH(BaseSH): 664 """Fortran Syntax Highlighter""" 665 # Syntax highlighting rules: 666 PROG = re.compile(make_fortran_patterns(), re.S|re.I) 667 IDPROG = re.compile(r"\s+(\w+)", re.S) 668 # Syntax highlighting states (from one text block to another): 669 NORMAL = 0 670 def __init__(self, parent, font=None, color_scheme=None): 671 BaseSH.__init__(self, parent, font, color_scheme) 672 673 def highlightBlock(self, text): 674 text = to_text_string(text) 675 self.setFormat(0, len(text), self.formats["normal"]) 676 677 match = self.PROG.search(text) 678 index = 0 679 while match: 680 for key, value in list(match.groupdict().items()): 681 if value: 682 start, end = match.span(key) 683 index += end-start 684 self.setFormat(start, end-start, self.formats[key]) 685 if value.lower() in ("subroutine", "module", "function"): 686 match1 = self.IDPROG.match(text, end) 687 if match1: 688 start1, end1 = match1.span(1) 689 self.setFormat(start1, end1-start1, 690 self.formats["definition"]) 691 692 match = self.PROG.search(text, match.end()) 693 694 self.highlight_spaces(text) 695 696class Fortran77SH(FortranSH): 697 """Fortran 77 Syntax Highlighter""" 698 def highlightBlock(self, text): 699 text = to_text_string(text) 700 if text.startswith(("c", "C")): 701 self.setFormat(0, len(text), self.formats["comment"]) 702 self.highlight_spaces(text) 703 else: 704 FortranSH.highlightBlock(self, text) 705 self.setFormat(0, 5, self.formats["comment"]) 706 self.setFormat(73, max([73, len(text)]), 707 self.formats["comment"]) 708 709 710#============================================================================== 711# IDL highlighter 712# 713# Contribution from Stuart Mumford (Littlemumford) - 02/02/2012 714# See Issue #850 715#============================================================================== 716def make_idl_patterns(): 717 "Strongly inspired from idlelib.ColorDelegator.make_pat" 718 kwstr = 'begin of pro function endfor endif endwhile endrep endcase endswitch end if then else for do while repeat until break case switch common continue exit return goto help message print read retall stop' 719 bistr1 = 'a_correlate abs acos adapt_hist_equal alog alog10 amoeba arg_present arra_equal array_indices ascii_template asin assoc atan beseli beselj besel k besely beta bilinear bin_date binary_template dinfgen dinomial blk_con broyden bytarr byte bytscl c_correlate call_external call_function ceil chebyshev check_math chisqr_cvf chisqr_pdf choldc cholsol cindgen clust_wts cluster color_quan colormap_applicable comfit complex complexarr complexround compute_mesh_normals cond congrid conj convert_coord convol coord2to3 correlate cos cosh cramer create_struct crossp crvlength ct_luminance cti_test curvefit cv_coord cvttobm cw_animate cw_arcball cw_bgroup cw_clr_index cw_colorsel cw_defroi cw_field cw_filesel cw_form cw_fslider cw_light_editor cw_orient cw_palette_editor cw_pdmenu cw_rgbslider cw_tmpl cw_zoom dblarr dcindgen dcomplexarr defroi deriv derivsig determ diag_matrix dialog_message dialog_pickfile pialog_printersetup dialog_printjob dialog_read_image dialog_write_image digital_filter dilate dindgen dist double eigenql eigenvec elmhes eof erode erf erfc erfcx execute exp expand_path expint extrac extract_slice f_cvf f_pdf factorial fft file_basename file_dirname file_expand_path file_info file_same file_search file_test file_which filepath findfile findgen finite fix float floor fltarr format_axis_values fstat fulstr fv_test fx_root fz_roots gamma gauss_cvf gauss_pdf gauss2dfit gaussfit gaussint get_drive_list get_kbrd get_screen_size getenv grid_tps grid3 griddata gs_iter hanning hdf_browser hdf_read hilbert hist_2d hist_equal histogram hough hqr ibeta identity idl_validname idlitsys_createtool igamma imaginary indgen int_2d int_3d int_tabulated intarr interpol interpolate invert ioctl ishft julday keword_set krig2d kurtosis kw_test l64indgen label_date label_region ladfit laguerre la_cholmprove la_cholsol la_Determ la_eigenproblem la_eigenql la_eigenvec la_elmhes la_gm_linear_model la_hqr la_invert la_least_square_equality la_least_squares la_linear_equation la_lumprove la_lusol la_trimprove la_trisol leefit legendre linbcg lindgen linfit ll_arc_distance lmfit lmgr lngamma lnp_test locale_get logical_and logical_or logical_true lon64arr lonarr long long64 lsode lu_complex lumprove lusol m_correlate machar make_array map_2points map_image map_patch map_proj_forward map_proj_init map_proj_inverse matrix_multiply matrix_power max md_test mean meanabsdev median memory mesh_clip mesh_decimate mesh_issolid mesh_merge mesh_numtriangles mesh_smooth mesh_surfacearea mesh_validate mesh_volume min min_curve_surf moment morph_close morph_distance morph_gradient morph_histormiss morph_open morph_thin morph_tophat mpeg_open msg_cat_open n_elements n_params n_tags newton norm obj_class obj_isa obj_new obj_valid objarr p_correlate path_sep pcomp pnt_line polar_surface poly poly_2d poly_area poly_fit polyfillv ployshade primes product profile profiles project_vol ptr_new ptr_valid ptrarr qgrid3 qromb qromo qsimp query_bmp query_dicom query_image query_jpeg query_mrsid query_pict query_png query_ppm query_srf query_tiff query_wav r_correlate r_test radon randomn randomu ranks read_ascii read_binary read_bmp read_dicom read_image read_mrsid read_png read_spr read_sylk read_tiff read_wav read_xwd real_part rebin recall_commands recon3 reform region_grow regress replicate reverse rk4 roberts rot rotate round routine_info rs_test s_test savgol search2d search3d sfit shift shmdebug shmvar simplex sin sindgen sinh size skewness smooth sobel sort sph_scat spher_harm spl_init spl_interp spline spline_p sprsab sprsax sprsin sprstp sqrt standardize stddev strarr strcmp strcompress stregex string strjoin strlen strlowcase strmatch strmessage strmid strpos strsplit strtrim strupcase svdfit svsol swap_endian systime t_cvf t_pdf tag_names tan tanh temporary tetra_clip tetra_surface tetra_volume thin timegen tm_test total trace transpose tri_surf trigrid trisol ts_coef ts_diff ts_fcast ts_smooth tvrd uindgen unit uintarr ul64indgen ulindgen ulon64arr ulonarr ulong ulong64 uniq value_locate variance vert_t3d voigt voxel_proj warp_tri watershed where widget_actevix widget_base widget_button widget_combobox widget_draw widget_droplist widget_event widget_info widget_label widget_list widget_propertsheet widget_slider widget_tab widget_table widget_text widget_tree write_sylk wtn xfont xregistered xsq_test' 720 bistr2 = 'annotate arrow axis bar_plot blas_axpy box_cursor breakpoint byteorder caldata calendar call_method call_procedure catch cd cir_3pnt close color_convert compile_opt constrained_min contour copy_lun cpu create_view cursor cw_animate_getp cw_animate_load cw_animate_run cw_light_editor_get cw_light_editor_set cw_palette_editor_get cw_palette_editor_set define_key define_msgblk define_msgblk_from_file defsysv delvar device dfpmin dissolve dlm_load doc_librar draw_roi efont empty enable_sysrtn erase errplot expand file_chmod file_copy file_delete file_lines file_link file_mkdir file_move file_readlink flick flow3 flush forward_function free_lun funct gamma_ct get_lun grid_input h_eq_ct h_eq_int heap_free heap_gc hls hsv icontour iimage image_cont image_statistics internal_volume iplot isocontour isosurface isurface itcurrent itdelete itgetcurrent itregister itreset ivolume journal la_choldc la_ludc la_svd la_tridc la_triql la_trired linkimage loadct ludc make_dll map_continents map_grid map_proj_info map_set mesh_obj mk_html_help modifyct mpeg_close mpeg_put mpeg_save msg_cat_close msg_cat_compile multi obj_destroy on_error on_ioerror online_help openr openw openu oplot oploterr particle_trace path_cache plot plot_3dbox plot_field ploterr plots point_lun polar_contour polyfill polywarp popd powell printf printd ps_show_fonts psafm pseudo ptr_free pushd qhull rdpix readf read_interfile read_jpeg read_pict read_ppm read_srf read_wave read_x11_bitmap reads readu reduce_colors register_cursor replicate_inplace resolve_all resolve_routine restore save scale3 scale3d set_plot set_shading setenv setup_keys shade_surf shade_surf_irr shade_volume shmmap show3 showfont skip_lun slicer3 slide_image socket spawn sph_4pnt streamline stretch strput struct_assign struct_hide surface surfr svdc swap_enian_inplace t3d tek_color threed time_test2 triangulate triql trired truncate_lun tv tvcrs tvlct tvscl usersym vector_field vel velovect voronoi wait wdelete wf_draw widget_control widget_displaycontextmenu window write_bmp write_image write_jpeg write_nrif write_pict write_png write_ppm write_spr write_srf write_tiff write_wav write_wave writeu wset wshow xbm_edit xdisplayfile xdxf xinteranimate xloadct xmanager xmng_tmpl xmtool xobjview xobjview_rotate xobjview_write_image xpalette xpcolo xplot3d xroi xsurface xvaredit xvolume xyouts zoom zoom_24' 721 kw = r"\b" + any("keyword", kwstr.split()) + r"\b" 722 builtin = r"\b" + any("builtin", bistr1.split()+bistr2.split()) + r"\b" 723 comment = any("comment", [r"\;[^\n]*"]) 724 number = any("number", 725 [r"\b[+-]?[0-9]+[lL]?\b", 726 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 727 r"\b\.[0-9]d0|\.d0+[lL]?\b", 728 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"]) 729 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 730 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 731 string = any("string", [sqstring, dqstring]) 732 return "|".join([kw, comment, string, number, builtin, 733 any("SYNC", [r"\n"])]) 734 735class IdlSH(GenericSH): 736 """IDL Syntax Highlighter""" 737 PROG = re.compile(make_idl_patterns(), re.S|re.I) 738 739 740#============================================================================== 741# Diff/Patch highlighter 742#============================================================================== 743 744class DiffSH(BaseSH): 745 """Simple Diff/Patch Syntax Highlighter Class""" 746 def highlightBlock(self, text): 747 text = to_text_string(text) 748 if text.startswith("+++"): 749 self.setFormat(0, len(text), self.formats["keyword"]) 750 elif text.startswith("---"): 751 self.setFormat(0, len(text), self.formats["keyword"]) 752 elif text.startswith("+"): 753 self.setFormat(0, len(text), self.formats["string"]) 754 elif text.startswith("-"): 755 self.setFormat(0, len(text), self.formats["number"]) 756 elif text.startswith("@"): 757 self.setFormat(0, len(text), self.formats["builtin"]) 758 759 self.highlight_spaces(text) 760 761#============================================================================== 762# NSIS highlighter 763#============================================================================== 764 765def make_nsis_patterns(): 766 "Strongly inspired from idlelib.ColorDelegator.make_pat" 767 kwstr1 = 'Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exec ExecShell ExecWait Exch ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileSeek FileWrite FileWriteByte FindClose FindFirst FindNext FindWindow FlushINI Function FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow ChangeUI CheckBitmap Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LogSet LogText MessageBox MiscButtonText Name OutFile Page PageCallbacks PageEx PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename ReserveFile Return RMDir SearchPath Section SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCpy StrLen SubCaption SubSection SubSectionEnd UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle' 768 kwstr2 = 'all alwaysoff ARCHIVE auto both bzip2 components current custom details directory false FILE_ATTRIBUTE_ARCHIVE FILE_ATTRIBUTE_HIDDEN FILE_ATTRIBUTE_NORMAL FILE_ATTRIBUTE_OFFLINE FILE_ATTRIBUTE_READONLY FILE_ATTRIBUTE_SYSTEM FILE_ATTRIBUTE_TEMPORARY force grey HIDDEN hide IDABORT IDCANCEL IDIGNORE IDNO IDOK IDRETRY IDYES ifdiff ifnewer instfiles instfiles lastused leave left level license listonly lzma manual MB_ABORTRETRYIGNORE MB_DEFBUTTON1 MB_DEFBUTTON2 MB_DEFBUTTON3 MB_DEFBUTTON4 MB_ICONEXCLAMATION MB_ICONINFORMATION MB_ICONQUESTION MB_ICONSTOP MB_OK MB_OKCANCEL MB_RETRYCANCEL MB_RIGHT MB_SETFOREGROUND MB_TOPMOST MB_YESNO MB_YESNOCANCEL nevershow none NORMAL off OFFLINE on READONLY right RO show silent silentlog SYSTEM TEMPORARY text textonly true try uninstConfirm windows zlib' 769 kwstr3 = 'MUI_ABORTWARNING MUI_ABORTWARNING_CANCEL_DEFAULT MUI_ABORTWARNING_TEXT MUI_BGCOLOR MUI_COMPONENTSPAGE_CHECKBITMAP MUI_COMPONENTSPAGE_NODESC MUI_COMPONENTSPAGE_SMALLDESC MUI_COMPONENTSPAGE_TEXT_COMPLIST MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE MUI_COMPONENTSPAGE_TEXT_INSTTYPE MUI_COMPONENTSPAGE_TEXT_TOP MUI_CUSTOMFUNCTION_ABORT MUI_CUSTOMFUNCTION_GUIINIT MUI_CUSTOMFUNCTION_UNABORT MUI_CUSTOMFUNCTION_UNGUIINIT MUI_DESCRIPTION_TEXT MUI_DIRECTORYPAGE_BGCOLOR MUI_DIRECTORYPAGE_TEXT_DESTINATION MUI_DIRECTORYPAGE_TEXT_TOP MUI_DIRECTORYPAGE_VARIABLE MUI_DIRECTORYPAGE_VERIFYONLEAVE MUI_FINISHPAGE_BUTTON MUI_FINISHPAGE_CANCEL_ENABLED MUI_FINISHPAGE_LINK MUI_FINISHPAGE_LINK_COLOR MUI_FINISHPAGE_LINK_LOCATION MUI_FINISHPAGE_NOAUTOCLOSE MUI_FINISHPAGE_NOREBOOTSUPPORT MUI_FINISHPAGE_REBOOTLATER_DEFAULT MUI_FINISHPAGE_RUN MUI_FINISHPAGE_RUN_FUNCTION MUI_FINISHPAGE_RUN_NOTCHECKED MUI_FINISHPAGE_RUN_PARAMETERS MUI_FINISHPAGE_RUN_TEXT MUI_FINISHPAGE_SHOWREADME MUI_FINISHPAGE_SHOWREADME_FUNCTION MUI_FINISHPAGE_SHOWREADME_NOTCHECKED MUI_FINISHPAGE_SHOWREADME_TEXT MUI_FINISHPAGE_TEXT MUI_FINISHPAGE_TEXT_LARGE MUI_FINISHPAGE_TEXT_REBOOT MUI_FINISHPAGE_TEXT_REBOOTLATER MUI_FINISHPAGE_TEXT_REBOOTNOW MUI_FINISHPAGE_TITLE MUI_FINISHPAGE_TITLE_3LINES MUI_FUNCTION_DESCRIPTION_BEGIN MUI_FUNCTION_DESCRIPTION_END MUI_HEADER_TEXT MUI_HEADER_TRANSPARENT_TEXT MUI_HEADERIMAGE MUI_HEADERIMAGE_BITMAP MUI_HEADERIMAGE_BITMAP_NOSTRETCH MUI_HEADERIMAGE_BITMAP_RTL MUI_HEADERIMAGE_BITMAP_RTL_NOSTRETCH MUI_HEADERIMAGE_RIGHT MUI_HEADERIMAGE_UNBITMAP MUI_HEADERIMAGE_UNBITMAP_NOSTRETCH MUI_HEADERIMAGE_UNBITMAP_RTL MUI_HEADERIMAGE_UNBITMAP_RTL_NOSTRETCH MUI_HWND MUI_ICON MUI_INSTALLCOLORS MUI_INSTALLOPTIONS_DISPLAY MUI_INSTALLOPTIONS_DISPLAY_RETURN MUI_INSTALLOPTIONS_EXTRACT MUI_INSTALLOPTIONS_EXTRACT_AS MUI_INSTALLOPTIONS_INITDIALOG MUI_INSTALLOPTIONS_READ MUI_INSTALLOPTIONS_SHOW MUI_INSTALLOPTIONS_SHOW_RETURN MUI_INSTALLOPTIONS_WRITE MUI_INSTFILESPAGE_ABORTHEADER_SUBTEXT MUI_INSTFILESPAGE_ABORTHEADER_TEXT MUI_INSTFILESPAGE_COLORS MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT MUI_INSTFILESPAGE_FINISHHEADER_TEXT MUI_INSTFILESPAGE_PROGRESSBAR MUI_LANGDLL_ALLLANGUAGES MUI_LANGDLL_ALWAYSSHOW MUI_LANGDLL_DISPLAY MUI_LANGDLL_INFO MUI_LANGDLL_REGISTRY_KEY MUI_LANGDLL_REGISTRY_ROOT MUI_LANGDLL_REGISTRY_VALUENAME MUI_LANGDLL_WINDOWTITLE MUI_LANGUAGE MUI_LICENSEPAGE_BGCOLOR MUI_LICENSEPAGE_BUTTON MUI_LICENSEPAGE_CHECKBOX MUI_LICENSEPAGE_CHECKBOX_TEXT MUI_LICENSEPAGE_RADIOBUTTONS MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_ACCEPT MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_DECLINE MUI_LICENSEPAGE_TEXT_BOTTOM MUI_LICENSEPAGE_TEXT_TOP MUI_PAGE_COMPONENTS MUI_PAGE_CUSTOMFUNCTION_LEAVE MUI_PAGE_CUSTOMFUNCTION_PRE MUI_PAGE_CUSTOMFUNCTION_SHOW MUI_PAGE_DIRECTORY MUI_PAGE_FINISH MUI_PAGE_HEADER_SUBTEXT MUI_PAGE_HEADER_TEXT MUI_PAGE_INSTFILES MUI_PAGE_LICENSE MUI_PAGE_STARTMENU MUI_PAGE_WELCOME MUI_RESERVEFILE_INSTALLOPTIONS MUI_RESERVEFILE_LANGDLL MUI_SPECIALINI MUI_STARTMENU_GETFOLDER MUI_STARTMENU_WRITE_BEGIN MUI_STARTMENU_WRITE_END MUI_STARTMENUPAGE_BGCOLOR MUI_STARTMENUPAGE_DEFAULTFOLDER MUI_STARTMENUPAGE_NODISABLE MUI_STARTMENUPAGE_REGISTRY_KEY MUI_STARTMENUPAGE_REGISTRY_ROOT MUI_STARTMENUPAGE_REGISTRY_VALUENAME MUI_STARTMENUPAGE_TEXT_CHECKBOX MUI_STARTMENUPAGE_TEXT_TOP MUI_UI MUI_UI_COMPONENTSPAGE_NODESC MUI_UI_COMPONENTSPAGE_SMALLDESC MUI_UI_HEADERIMAGE MUI_UI_HEADERIMAGE_RIGHT MUI_UNABORTWARNING MUI_UNABORTWARNING_CANCEL_DEFAULT MUI_UNABORTWARNING_TEXT MUI_UNCONFIRMPAGE_TEXT_LOCATION MUI_UNCONFIRMPAGE_TEXT_TOP MUI_UNFINISHPAGE_NOAUTOCLOSE MUI_UNFUNCTION_DESCRIPTION_BEGIN MUI_UNFUNCTION_DESCRIPTION_END MUI_UNGETLANGUAGE MUI_UNICON MUI_UNPAGE_COMPONENTS MUI_UNPAGE_CONFIRM MUI_UNPAGE_DIRECTORY MUI_UNPAGE_FINISH MUI_UNPAGE_INSTFILES MUI_UNPAGE_LICENSE MUI_UNPAGE_WELCOME MUI_UNWELCOMEFINISHPAGE_BITMAP MUI_UNWELCOMEFINISHPAGE_BITMAP_NOSTRETCH MUI_UNWELCOMEFINISHPAGE_INI MUI_WELCOMEFINISHPAGE_BITMAP MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH MUI_WELCOMEFINISHPAGE_CUSTOMFUNCTION_INIT MUI_WELCOMEFINISHPAGE_INI MUI_WELCOMEPAGE_TEXT MUI_WELCOMEPAGE_TITLE MUI_WELCOMEPAGE_TITLE_3LINES' 770 bistr = 'addincludedir addplugindir AndIf cd define echo else endif error execute If ifdef ifmacrodef ifmacrondef ifndef include insertmacro macro macroend onGUIEnd onGUIInit onInit onInstFailed onInstSuccess onMouseOverSection onRebootFailed onSelChange onUserAbort onVerifyInstDir OrIf packhdr system undef verbose warning' 771 instance = any("instance", [r'\$\{.*?\}', r'\$[A-Za-z0-9\_]*']) 772 define = any("define", [r"\![^\n]*"]) 773 comment = any("comment", [r"\;[^\n]*", r"\#[^\n]*", r"\/\*(.*?)\*\/"]) 774 return make_generic_c_patterns(kwstr1+' '+kwstr2+' '+kwstr3, bistr, 775 instance=instance, define=define, 776 comment=comment) 777 778class NsisSH(CppSH): 779 """NSIS Syntax Highlighter""" 780 # Syntax highlighting rules: 781 PROG = re.compile(make_nsis_patterns(), re.S) 782 783 784#============================================================================== 785# gettext highlighter 786#============================================================================== 787 788def make_gettext_patterns(): 789 "Strongly inspired from idlelib.ColorDelegator.make_pat" 790 kwstr = 'msgid msgstr' 791 kw = r"\b" + any("keyword", kwstr.split()) + r"\b" 792 fuzzy = any("builtin", [r"#,[^\n]*"]) 793 links = any("normal", [r"#:[^\n]*"]) 794 comment = any("comment", [r"#[^\n]*"]) 795 number = any("number", 796 [r"\b[+-]?[0-9]+[lL]?\b", 797 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 798 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"]) 799 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 800 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 801 string = any("string", [sqstring, dqstring]) 802 return "|".join([kw, string, number, fuzzy, links, comment, 803 any("SYNC", [r"\n"])]) 804 805class GetTextSH(GenericSH): 806 """gettext Syntax Highlighter""" 807 # Syntax highlighting rules: 808 PROG = re.compile(make_gettext_patterns(), re.S) 809 810#============================================================================== 811# yaml highlighter 812#============================================================================== 813 814def make_yaml_patterns(): 815 "Strongly inspired from sublime highlighter " 816 kw = any("keyword", [r":|>|-|\||\[|\]|[A-Za-z][\w\s\-\_ ]+(?=:)"]) 817 links = any("normal", [r"#:[^\n]*"]) 818 comment = any("comment", [r"#[^\n]*"]) 819 number = any("number", 820 [r"\b[+-]?[0-9]+[lL]?\b", 821 r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", 822 r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"]) 823 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 824 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 825 string = any("string", [sqstring, dqstring]) 826 return "|".join([kw, string, number, links, comment, 827 any("SYNC", [r"\n"])]) 828 829class YamlSH(GenericSH): 830 """yaml Syntax Highlighter""" 831 # Syntax highlighting rules: 832 PROG = re.compile(make_yaml_patterns(), re.S) 833 834 835#============================================================================== 836# HTML highlighter 837#============================================================================== 838 839class BaseWebSH(BaseSH): 840 """Base class for CSS and HTML syntax highlighters""" 841 NORMAL = 0 842 COMMENT = 1 843 844 def __init__(self, parent, font=None, color_scheme=None): 845 BaseSH.__init__(self, parent, font, color_scheme) 846 847 def highlightBlock(self, text): 848 text = to_text_string(text) 849 previous_state = self.previousBlockState() 850 851 if previous_state == self.COMMENT: 852 self.setFormat(0, len(text), self.formats["comment"]) 853 else: 854 previous_state = self.NORMAL 855 self.setFormat(0, len(text), self.formats["normal"]) 856 857 self.setCurrentBlockState(previous_state) 858 match = self.PROG.search(text) 859 860 match_count = 0 861 n_characters = len(text) 862 # There should never be more matches than characters in the text. 863 while match and match_count < n_characters: 864 match_dict = match.groupdict() 865 for key, value in list(match_dict.items()): 866 if value: 867 start, end = match.span(key) 868 if previous_state == self.COMMENT: 869 if key == "multiline_comment_end": 870 self.setCurrentBlockState(self.NORMAL) 871 self.setFormat(end, len(text), 872 self.formats["normal"]) 873 else: 874 self.setCurrentBlockState(self.COMMENT) 875 self.setFormat(0, len(text), 876 self.formats["comment"]) 877 else: 878 if key == "multiline_comment_start": 879 self.setCurrentBlockState(self.COMMENT) 880 self.setFormat(start, len(text), 881 self.formats["comment"]) 882 else: 883 self.setCurrentBlockState(self.NORMAL) 884 try: 885 self.setFormat(start, end-start, 886 self.formats[key]) 887 except KeyError: 888 # happens with unmatched end-of-comment; 889 # see issue 1462 890 pass 891 892 match = self.PROG.search(text, match.end()) 893 match_count += 1 894 895 self.highlight_spaces(text) 896 897def make_html_patterns(): 898 """Strongly inspired from idlelib.ColorDelegator.make_pat """ 899 tags = any("builtin", [r"<", r"[\?/]?>", r"(?<=<).*?(?=[ >])"]) 900 keywords = any("keyword", [r" [\w:-]*?(?==)"]) 901 string = any("string", [r'".*?"']) 902 comment = any("comment", [r"<!--.*?-->"]) 903 multiline_comment_start = any("multiline_comment_start", [r"<!--"]) 904 multiline_comment_end = any("multiline_comment_end", [r"-->"]) 905 return "|".join([comment, multiline_comment_start, 906 multiline_comment_end, tags, keywords, string]) 907 908class HtmlSH(BaseWebSH): 909 """HTML Syntax Highlighter""" 910 PROG = re.compile(make_html_patterns(), re.S) 911 912 913# ============================================================================= 914# Markdown highlighter 915# ============================================================================= 916 917def make_md_patterns(): 918 h1 = '^#[^#]+' 919 h2 = '^##[^#]+' 920 h3 = '^###[^#]+' 921 h4 = '^####[^#]+' 922 h5 = '^#####[^#]+' 923 h6 = '^######[^#]+' 924 925 titles = any('title', [h1, h2, h3, h4, h5, h6]) 926 927 html_tags = any("builtin", [r"<", r"[\?/]?>", r"(?<=<).*?(?=[ >])"]) 928 html_symbols = '&[^; ].+;' 929 html_comment = '<!--.+-->' 930 931 strikethrough = any('strikethrough', [r'(~~)(.*?)~~']) 932 strong = any('strong', [r'(\*\*)(.*?)\*\*']) 933 934 italic = r'(__)(.*?)__' 935 emphasis = r'(//)(.*?)//' 936 italic = any('italic', [italic, emphasis]) 937 938 # links - (links) after [] or links after []: 939 link_html = (r'(?<=(\]\())[^\(\)]*(?=\))|' 940 '(<https?://[^>]+>)|' 941 '(<[^ >]+@[^ >]+>)') 942 # link/image references - [] or ![] 943 link = r'!?\[[^\[\]]*\]' 944 links = any('link', [link_html, link]) 945 946 # blockquotes and lists - > or - or * or 0. 947 blockquotes = (r'(^>+.*)' 948 r'|(^(?: |\t)*[0-9]+\. )' 949 r'|(^(?: |\t)*- )' 950 r'|(^(?: |\t)*\* )') 951 # code 952 code = any('code', ['^`{3,}.*$']) 953 inline_code = any('inline_code', ['`[^`]*`']) 954 955 # math - $$ 956 math = any('number', [r'^(?:\${2}).*$', html_symbols]) 957 958 comment = any('comment', [blockquotes, html_comment]) 959 960 return '|'.join([titles, comment, html_tags, math, links, italic, strong, 961 strikethrough, code, inline_code]) 962 963 964class MarkdownSH(BaseSH): 965 """Markdown Syntax Highlighter""" 966 # Syntax highlighting rules: 967 PROG = re.compile(make_md_patterns(), re.S) 968 NORMAL = 0 969 CODE = 1 970 971 def highlightBlock(self, text): 972 text = to_text_string(text) 973 previous_state = self.previousBlockState() 974 975 if previous_state == self.CODE: 976 self.setFormat(0, len(text), self.formats["code"]) 977 else: 978 previous_state = self.NORMAL 979 self.setFormat(0, len(text), self.formats["normal"]) 980 981 self.setCurrentBlockState(previous_state) 982 983 match = self.PROG.search(text) 984 match_count = 0 985 n_characters = len(text) 986 987 while match and match_count< n_characters: 988 for key, value in list(match.groupdict().items()): 989 start, end = match.span(key) 990 991 if value: 992 previous_state = self.previousBlockState() 993 994 if previous_state == self.CODE: 995 if key == "code": 996 # Change to normal 997 self.setFormat(0, len(text), 998 self.formats["normal"]) 999 self.setCurrentBlockState(self.NORMAL) 1000 else: 1001 continue 1002 else: 1003 if key == "code": 1004 # Change to code 1005 self.setFormat(0, len(text), self.formats["code"]) 1006 self.setCurrentBlockState(self.CODE) 1007 continue 1008 1009 self.setFormat(start, end - start, self.formats[key]) 1010 1011 match = self.PROG.search(text, match.end()) 1012 match_count += 1 1013 1014 self.highlight_spaces(text) 1015 1016 def setup_formats(self, font=None): 1017 super(MarkdownSH, self).setup_formats(font) 1018 1019 font = QTextCharFormat(self.formats['normal']) 1020 font.setFontItalic(True) 1021 self.formats['italic'] = font 1022 1023 self.formats['strong'] = self.formats['definition'] 1024 1025 font = QTextCharFormat(self.formats['normal']) 1026 font.setFontStrikeOut(True) 1027 self.formats['strikethrough'] = font 1028 1029 font = QTextCharFormat(self.formats['string']) 1030 font.setUnderlineStyle(True) 1031 self.formats['link'] = font 1032 1033 self.formats['code'] = self.formats['string'] 1034 self.formats['inline_code'] = self.formats['string'] 1035 1036 font = QTextCharFormat(self.formats['keyword']) 1037 font.setFontWeight(QFont.Bold) 1038 self.formats['title'] = font 1039 1040 1041#============================================================================== 1042# Pygments based omni-parser 1043#============================================================================== 1044 1045# IMPORTANT NOTE: 1046# -------------- 1047# Do not be tempted to generalize the use of PygmentsSH (that is tempting 1048# because it would lead to more generic and compact code, and not only in 1049# this very module) because this generic syntax highlighter is far slower 1050# than the native ones (all classes above). For example, a Python syntax 1051# highlighter based on PygmentsSH would be 2 to 3 times slower than the 1052# current native PythonSH syntax highlighter. 1053 1054class PygmentsSH(BaseSH): 1055 """ Generic Pygments syntax highlighter """ 1056 # Store the language name and a ref to the lexer 1057 _lang_name = None 1058 _lexer = None 1059 1060 # Syntax highlighting states (from one text block to another): 1061 NORMAL = 0 1062 def __init__(self, parent, font=None, color_scheme=None): 1063 # Warning: do not move out those import statements 1064 # (pygments is an optional dependency) 1065 from pygments.lexers import get_lexer_by_name 1066 from pygments.token import (Text, Other, Keyword, Name, String, Number, 1067 Comment, Generic, Token) 1068 # Map Pygments tokens to Spyder tokens 1069 self._tokmap = {Text: "normal", 1070 Generic: "normal", 1071 Other: "normal", 1072 Keyword: "keyword", 1073 Token.Operator: "normal", 1074 Name.Builtin: "builtin", 1075 Name: "normal", 1076 Comment: "comment", 1077 String: "string", 1078 Number: "number"} 1079 # Load Pygments' Lexer 1080 if self._lang_name is not None: 1081 self._lexer = get_lexer_by_name(self._lang_name) 1082 1083 BaseSH.__init__(self, parent, font, color_scheme) 1084 1085 # This worker runs in a thread to avoid blocking when doing full file 1086 # parsing 1087 self._worker_manager = WorkerManager() 1088 1089 # Store the format for all the tokens after Pygments parsing 1090 self._charlist = [] 1091 1092 # Flag variable to avoid unnecessary highlights if the worker has not 1093 # yet finished processing 1094 self._allow_highlight = True 1095 1096 def make_charlist(self): 1097 """Parses the complete text and stores format for each character.""" 1098 1099 def worker_output(worker, output, error): 1100 """Worker finished callback.""" 1101 self._charlist = output 1102 if error is None and output: 1103 self._allow_highlight = True 1104 self.rehighlight() 1105 self._allow_highlight = False 1106 1107 text = to_text_string(self.document().toPlainText()) 1108 tokens = self._lexer.get_tokens(text) 1109 1110 # Before starting a new worker process make sure to end previous 1111 # incarnations 1112 self._worker_manager.terminate_all() 1113 1114 worker = self._worker_manager.create_python_worker( 1115 self._make_charlist, 1116 tokens, 1117 self._tokmap, 1118 self.formats, 1119 ) 1120 worker.sig_finished.connect(worker_output) 1121 worker.start() 1122 1123 def _make_charlist(self, tokens, tokmap, formats): 1124 """ 1125 Parses the complete text and stores format for each character. 1126 1127 Uses the attached lexer to parse into a list of tokens and Pygments 1128 token types. Then breaks tokens into individual letters, each with a 1129 Spyder token type attached. Stores this list as self._charlist. 1130 1131 It's attached to the contentsChange signal of the parent QTextDocument 1132 so that the charlist is updated whenever the document changes. 1133 """ 1134 1135 def _get_fmt(typ): 1136 """Get the Spyder format code for the given Pygments token type.""" 1137 # Exact matches first 1138 if typ in tokmap: 1139 return tokmap[typ] 1140 # Partial (parent-> child) matches 1141 for key, val in tokmap.items(): 1142 if typ in key: # Checks if typ is a subtype of key. 1143 return val 1144 1145 return 'normal' 1146 1147 charlist = [] 1148 for typ, token in tokens: 1149 fmt = formats[_get_fmt(typ)] 1150 for letter in token: 1151 charlist.append((fmt, letter)) 1152 1153 return charlist 1154 1155 def highlightBlock(self, text): 1156 """ Actually highlight the block""" 1157 # Note that an undefined blockstate is equal to -1, so the first block 1158 # will have the correct behaviour of starting at 0. 1159 if self._allow_highlight: 1160 start = self.previousBlockState() + 1 1161 end = start + len(text) 1162 for i, (fmt, letter) in enumerate(self._charlist[start:end]): 1163 self.setFormat(i, 1, fmt) 1164 self.setCurrentBlockState(end) 1165 self.highlight_spaces(text) 1166 1167 1168def guess_pygments_highlighter(filename): 1169 """Factory to generate syntax highlighter for the given filename. 1170 1171 If a syntax highlighter is not available for a particular file, this 1172 function will attempt to generate one based on the lexers in Pygments. If 1173 Pygments is not available or does not have an appropriate lexer, TextSH 1174 will be returned instead. 1175 1176 """ 1177 try: 1178 from pygments.lexers import get_lexer_for_filename, get_lexer_by_name 1179 from pygments.util import ClassNotFound 1180 except ImportError: 1181 return TextSH 1182 root, ext = os.path.splitext(filename) 1183 if ext in custom_extension_lexer_mapping: 1184 lexer = get_lexer_by_name(custom_extension_lexer_mapping[ext]) 1185 else: 1186 try: 1187 lexer = get_lexer_for_filename(filename) 1188 except ClassNotFound: 1189 return TextSH 1190 class GuessedPygmentsSH(PygmentsSH): 1191 _lexer = lexer 1192 return GuessedPygmentsSH 1193