示例#1
0
    def apply_filter(self, *args):
        text = self.filterEdit.text()
        if text:
            if self.filter_columns.currentText() == "name":
                m = QRegularExpression(text)
                if m.isValid():
                    if self.name_regex_option.currentText(
                    ) == "case-insensitive":
                        m.setPatternOptions(
                            QRegularExpression.CaseInsensitiveOption)

                    m.optimize()
                    filter = lambda row_num: m.match(
                        self.table.item(row_num, 0).text()).hasMatch()
                else:
                    return

            elif self.filter_columns.currentText() == "denticity":
                if text.isdigit():
                    filter = lambda row_num: int(
                        self.table.item(row_num, 1).text()) == int(text)
                else:
                    filter = lambda row: True

            elif self.filter_columns.currentText() == "coordinating elements":
                method = self.coordinating_elements_method.currentText()

                def filter(row_num):
                    row_key_atoms = [
                        item.strip() for item in self.table.item(
                            row_num, 2).text().split(',')
                    ]
                    search_atoms = []
                    for item in text.split():
                        for ele in item.split(','):
                            if ele.strip() != "":
                                search_atoms.append(ele)

                    if method == "exactly":
                        if all([row_key_atoms.count(element) == search_atoms.count(element) for element in set(search_atoms)]) and \
                            all([row_key_atoms.count(element) == search_atoms.count(element) for element in set(row_key_atoms)]):
                            return True
                        else:
                            return False

                    elif method == "at least":
                        if all([
                                row_key_atoms.count(element) >=
                                search_atoms.count(element)
                                for element in set(search_atoms)
                        ]):
                            return True
                        else:
                            return False

        else:
            filter = lambda row: True

        for i in range(0, self.table.rowCount()):
            self.table.setRowHidden(i, not filter(i))
示例#2
0
class WorkspaceNameValidator(QValidator):
    def __init__(self):
        self.regex = QRegularExpression(r"^.{1,256}$")

    def validate(self, string, pos):
        if self.regex.match(string, pos).hasMatch():
            return QValidator.Acceptable, string, pos
        return QValidator.Invalid, string, pos
示例#3
0
def rxExecute(regexp, options, text, startpos):
    """
    Function to execute the given regular expression for a given text.
    
    @param regexp regular expression to validate (string)
    @param options list of options (list of string)
    @param text text to execute on (string)
    @param startpos start position for the execution (integer)
    @return tuple of a flag indicating a successful match (boolean) and
        a list of captures containing the complete match as matched string
        (string), match start (integer), match end (integer) and match length
        (integer) for each entry
    """
    valid, error, errorOffset = rxValidate(regexp, options)
    if not valid:
        return valid, error, errorOffset

    from PyQt5.QtCore import QRegularExpression
    rxOptions = QRegularExpression.NoPatternOption
    if "CaseInsensitiveOption" in options:
        rxOptions |= QRegularExpression.CaseInsensitiveOption
    if "MultilineOption" in options:
        rxOptions |= QRegularExpression.MultilineOption
    if "DotMatchesEverythingOption" in options:
        rxOptions |= QRegularExpression.DotMatchesEverythingOption
    if "ExtendedPatternSyntaxOption" in options:
        rxOptions |= QRegularExpression.ExtendedPatternSyntaxOption
    if "InvertedGreedinessOption" in options:
        rxOptions |= QRegularExpression.InvertedGreedinessOption
    if "UseUnicodePropertiesOption" in options:
        rxOptions |= QRegularExpression.UseUnicodePropertiesOption
    if "DontCaptureOption" in options:
        rxOptions |= QRegularExpression.DontCaptureOption

    matched = False
    captures = []
    re = QRegularExpression(regexp, rxOptions)
    match = re.match(text, startpos)
    if match.hasMatch():
        matched = True
        for index in range(match.lastCapturedIndex() + 1):
            captures.append([
                match.captured(index),
                match.capturedStart(index),
                match.capturedEnd(index),
                match.capturedLength(index)
            ])

    return matched, captures
def rxExecute(regexp, options, text, startpos):
    """
    Function to execute the given regular expression for a given text.
    
    @param regexp regular expression to validate (string)
    @param options list of options (list of string)
    @param text text to execute on (string)
    @param startpos start position for the execution (integer)
    @return tuple of a flag indicating a successful match (boolean) and
        a list of captures containing the complete match as matched string
        (string), match start (integer), match end (integer) and match length
        (integer) for each entry
    """
    valid, error, errorOffset = rxValidate(regexp, options)
    if not valid:
        return valid, error, errorOffset
    
    from PyQt5.QtCore import QRegularExpression
    rxOptions = QRegularExpression.NoPatternOption
    if "CaseInsensitiveOption" in options:
        rxOptions |= QRegularExpression.CaseInsensitiveOption
    if "MultilineOption" in options:
        rxOptions |= QRegularExpression.MultilineOption
    if "DotMatchesEverythingOption" in options:
        rxOptions |= QRegularExpression.DotMatchesEverythingOption
    if "ExtendedPatternSyntaxOption" in options:
        rxOptions |= QRegularExpression.ExtendedPatternSyntaxOption
    if "InvertedGreedinessOption" in options:
        rxOptions |= QRegularExpression.InvertedGreedinessOption
    if "UseUnicodePropertiesOption" in options:
        rxOptions |= QRegularExpression.UseUnicodePropertiesOption
    if "DontCaptureOption" in options:
        rxOptions |= QRegularExpression.DontCaptureOption
    
    matched = False
    captures = []
    re = QRegularExpression(regexp, rxOptions)
    match = re.match(text, startpos)
    if match.hasMatch():
        matched = True
        for index in range(match.lastCapturedIndex() + 1):
            captures.append([
                match.captured(index),
                match.capturedStart(index),
                match.capturedEnd(index),
                match.capturedLength(index)
            ])
    
    return matched, captures
示例#5
0
class BinValidator(QValidator):
    def __init__(self, max_bits=-1, bit_group_size=4):
        super().__init__()

        self.max_bits = max_bits
        self.bit_group_size = bit_group_size

        if max_bits == 0:
            self.re_acceptable = QRegularExpression('')
        elif max_bits > 0:
            self.re_acceptable = QRegularExpression(
                '^([0,1](\s[0,1]){0,%d})?$' % (max_bits - 1))
            self.re_intermediate = QRegularExpression('^(\s*[0,1]){0,%d}\s*$' %
                                                      (max_bits))
        else:
            self.re_acceptable = QRegularExpression('^([0,1](\s[0,1])*)?$')
            self.re_intermediate = QRegularExpression('^(\s*[0,1])*\s*$')

    def validate(self, text, _pos):
        text = text.upper()

        if self.re_acceptable.match(text).hasMatch():
            return QValidator.Acceptable, text, _pos

        if self.re_intermediate.match(text).hasMatch():
            return QValidator.Intermediate, text, _pos

        return QValidator.Invalid, text, _pos

    def fixup(self, text):
        text = text.replace(' ', '')
        fixed = ' '.join([
            text[i:i + self.bit_group_size]
            for i in range(0, len(text), self.bit_group_size)
        ])
        return fixed
示例#6
0
    def apply_filter(self, *args):
        text = self.filterEdit.text()
        if text:
            if self.filter_columns.currentText() == "name":
                m = QRegularExpression(text)
                if m.isValid():
                    if self.name_regex_option.currentText(
                    ) == "case-insensitive":
                        m.setPatternOptions(
                            QRegularExpression.CaseInsensitiveOption)

                    m.optimize()
                    filter = lambda row_num: m.match(
                        self.table.item(row_num, 0).text()).hasMatch()
                else:
                    return

        else:
            filter = lambda row: True

        for i in range(0, self.table.rowCount()):
            self.table.setRowHidden(i, not filter(i))
示例#7
0
    def apply_filter(self, text=None):
        if text is None:
            text = self.filter.text()

        if text:
            text = text.replace("(", "\(")
            text = text.replace(")", "\)")
            m = QRegularExpression(text)
            m.setPatternOptions(QRegularExpression.CaseInsensitiveOption)
            if m.isValid():
                m.optimize()
                filter = lambda row_num: m.match(
                    self.table.item(row_num, 0).text()
                    if self.table.item(row_num, 0) is not None else self.table.
                    cellWidget(row_num, 0).text().replace("<sub>", "").replace(
                        "</sub>", "")).hasMatch()
            else:
                return

        else:
            filter = lambda row: True

        for i in range(0, self.table.rowCount()):
            self.table.setRowHidden(i, not filter(i))
示例#8
0
 def occurenceLineList(self, regex: QRegularExpression) -> List[int]:
     res = []
     for ind, line in enumerate(self._contentList):
         if regex.match(line).hasMatch():
             res.append(ind)
     return res
示例#9
0
 def contains(self, regex: QRegularExpression, useRegExp=True) -> bool:
     if useRegExp:
         match: QRegularExpressionMatch = regex.match(self._content)
         return match.hasMatch()
     else:
         return regex.pattern().lower() in self._contentLower
示例#10
0
 def valueFromText(text):
     regExp = QRegularExpression("(\\d+)(\\s*[xx]\\s*\\d+)?")
     match = regExp.match(text)
     if match.isValid():
         return match.captured(1).toInt()
     return 0
示例#11
0
class GMHighlighter(QSyntaxHighlighter):
    def __init__(self, document, base, proc_class):
        QSyntaxHighlighter.__init__(self, document)
        self.reversal_post_processor = proc_class(base)
        self.list_number_captured_1 = [i * 2
                                       for i in range(1, 15)]  #todo добавь ijk
        self.list_number_captured_1.insert(3, 6)
        self.previous_block_g = 0
        self.base = base
        self.count = 0
        self.count_in_step = 0
        self.const_step = 1000
        self.standart_step = self.const_step
        self.main_rule_regular_expression = QRegularExpression(
            self.reversal_post_processor.sorted_axis_rule)
        self.simple_format = STYLES['axis']  #self.first_rule[2]
        self.second_rule_regular_expression = QRegularExpression(
            self.reversal_post_processor.unsorted_axis_rule)  #self.rules[0][0]
        self.too_little_number_check()
        print(self.main_rule_regular_expression)

    def remember_np_box_parts(self, current_pool):

        self.current_g_cod_pool = current_pool

        #print('1 self.current_g_cod_pool = ')
        #print(self.current_g_cod_pool)
        #print('2 self.current_g_cod_pool = ')

    def too_little_number_check(self):
        print('too_little_number_check')
        if self.base.reading_lines_number < self.const_step:
            self.standart_step = self.base.reading_lines_number

    def highlightBlock(self, text):
        """Применить выделение синтаксиса к данному блоку текста. """
        #print('highloght text = [{}]'.format(text) )
        nya = self.main_rule_regular_expression.match(text, 0)
        #print('nya0 = ', nya.captured(0))
        start = nya.capturedStart()
        len_match = nya.capturedLength()
        if len_match != 0:
            #print('nya = ', nya.captured())
            self.recount(nya, STYLES_list_G0, STYLES_list_G1)

        elif start == 0:
            print('empty string')
            self.recount_empty_line()
            #print('index = {}, string = {}, запуск дополнительных правил'.format(index, text))
        else:
            nya = self.second_rule_regular_expression.match(text, 0)
            len_match = nya.capturedLength()
            if len_match != 0:
                self.unsorted_recount(nya, STYLES_list_G0, STYLES_list_G1)
            else:
                if not self.recount_special_rules(text):
                    print('ERROR LINE: ', text)

    def recount_empty_line(self):
        self.current_g_cod_pool[self.count][2] = self.previous_block_g
        self.current_g_cod_pool[self.count][16] = 9999  #type
        self.count_in_step += 1
        self.count += 1
        if self.count_in_step == self.standart_step:
            self.base.on_count_changed(self.count)  # progressBar
        return

    def recount_special_rules(self, text):
        self.current_g_cod_pool[self.count][3] = self.previous_block_g
        result = self.special_rare_case(text, self.count)
        self.count_in_step += 1
        self.count += 1
        if self.count_in_step == self.standart_step:
            self.base.on_count_changed(self.count)  # progressBar
        return result

    def special_rare_case(self, text, count):
        #print('self.base.current_g_cod_pool[self.count] ', self.base.current_g_cod_pool[self.count])
        #G28 U0. V0.
        print('text = ', text)
        if self.reversal_post_processor.check_command(
                self, text, self.current_g_cod_pool[count], count,
                self.base.g_modal):  #todo это не тот g_modal
            return True
        else:
            return False

        #print('self.start_pointXYZ = ', self.reversal_post_processor.start_pointXYZ)

    def recount(self, nya, STYLES_list_G0, STYLES_list_G1):

        #print('recount self.current_g_cod_pool = ', self.current_g_cod_pool)
        self.current_g_cod_pool[self.count, np.r_[0:15]] = [
            nya.captured(i) or None for i in self.list_number_captured_1
        ]
        #print('uuuu nya.captured(6) = ', nya.captured(6))
        #Заполнения здесь не происходит, так как оно только между numpy массивами
        #print('current_g_cod_pool == ', self.base.current_g_cod_pool[self.count])
        #G0-G3
        if np.isnan(self.current_g_cod_pool[self.count][3]):
            self.current_g_cod_pool[self.count][3] = self.previous_block_g
        else:
            self.previous_block_g = self.current_g_cod_pool[self.count][3]
            self.current_g_cod_pool[self.count, 2] = self.previous_block_g
        stile = STYLES_list_G0 if self.previous_block_g == 0 else STYLES_list_G1
        #colors
        # простая подсветка одним цветом
        # self.setFormat(index, len_match, self.simple_format)
        #полноценная подсветка
        i = 0
        ax = len(nya.captured(i * 2 + 1))
        start = 0
        #if ax != 0:
        #    self.setFormat(start, ax, stile[i])
        #start = start + ax
        #i = i + 1
        #print('i equal ', i)
        #for k in range(40):
        #    print('recount: ||||nya.captured({}) = {}'.format(k, nya.captured(k)))

        while i < 14:  #todo надо подумать. По идее надо добавлять +1 строку в style, но работало, вроде...
            if ax != 0:
                self.setFormat(start, ax, stile[i])
                #print('i = ', i)
                #print('stile[i] = ', stile[i])
            start = start + ax
            i = i + 1
            ax = len(nya.captured(i * 2 + 1))

        #print('recount current_g_cod_pool again == ', self.current_g_cod_pool[self.count])
        self.count_in_step += 1
        self.count += 1
        if self.count_in_step == self.standart_step:
            self.base.on_count_changed(self.count)
            #QApplication.processEvents()
        #print('Count')
        return

    def unsorted_recount(self, nya, STYLES_list_G0, STYLES_list_G1):
        print('unsorted_recount start')

        #for i in range(35):
        #    print('nya.captured({}) = {}'.format(i, nya.captured(i)))
        # G0-G3
        self.current_g_cod_pool[self.count][0] = nya.captured(2) or None
        self.current_g_cod_pool[self.count][1] = nya.captured(4) or None
        self.current_g_cod_pool[self.count][2] = nya.captured(6) or None
        if np.isnan(self.current_g_cod_pool[self.count][2]):
            self.current_g_cod_pool[self.count][3] = self.previous_block_g
        else:
            self.previous_block_g = self.current_g_cod_pool[self.count][2]
            self.current_g_cod_pool[self.count][3] = self.previous_block_g

        stile = STYLES_list_G0 if self.previous_block_g == 0 else STYLES_list_G1
        start = 0
        n = 1  #N
        ax = len(nya.captured(n))

        #print('n === ', n)
        #print('nya.captured(n) = ', nya.captured(n))
        #print(' ax  == ', ax )
        #print('start === ', start)

        if ax != 0:
            self.setFormat(start, ax, stile[0])  #N
            start = start + ax
        n = n + 2
        ax = len(nya.captured(n))

        if ax != 0:
            self.setFormat(start, ax, stile[1])  #G40
            start = start + ax
        n = n + 2
        ax = len(nya.captured(n))
        if ax != 0:
            self.setFormat(start, ax, stile[2])  #G1
            start = start + ax
        n = n + 2
        ax = len(nya.captured(n))

        #if ax != 0:
        #    self.setFormat(start, ax, stile[n-1])
        #    start = start + ax
        #n = n + 2
        #ax = len(nya.captured(n))
        n = n + 1
        #print('n === ', n)
        #for k in range(40):
        #    print('||||nya.captured({}) = {}'.format(k, nya.captured(k)))

        #n = 4
        while nya.captured(n) != '' and n < 26:  #вероятно, избыточное условие
            self.nesting(n, nya, start, ax, stile)
            start = start + ax
            n = n + 3
            ax = len(nya.captured(n - 1))
        #n = 26
        #ax = len(nya.captured(n))#todo нужно будет разделить координаты точки и IJK или уже?

        while nya.captured(n) != '' and n < 33:  #ijk
            self.nestingIJK(n, nya, start, ax, stile)
            start = start + ax
            n = n + 3
            ax = len(nya.captured(n - 1))
        #print('n = {}, ax = {}'.format(n, ax))

        #for i in range (33):
        #    print('nya.captured({}) = {}'.format(i, nya.captured(i)))
        n = 35
        ax = len(nya.captured(n - 1))
        print('n 2=== ', n)
        #ax = len(nya.captured(34))
        if ax != 0:
            self.setFormat(start, ax, stile[12])
            start = start + ax
        self.current_g_cod_pool[self.count][13] = nya.captured(35) or None  #R
        #ax = len(nya.captured(29))

        n = 37
        ax = len(nya.captured(n - 1))
        if ax != 0:
            self.setFormat(start, ax, stile[13])
            #start = start + ax
        self.current_g_cod_pool[self.count][14] = nya.captured(37) or None  #F
        print('unsorted recount current_g_cod_pool again == ',
              self.current_g_cod_pool[self.count])
        self.count_in_step += 1
        self.count += 1
        if self.count_in_step == self.standart_step:
            self.base.on_count_changed(self.count)  # progressBar
            # QApplication.processEvents()
        return

    def nestingIJK(self, n, nya, start, ax, stile):
        print('nestingIJK')
        add = 2
        symbol = nya.captured(n)
        if symbol == 'I':
            i = 7 + add
        elif symbol == 'J':
            i = 8 + add
        elif symbol == 'K':
            i = 9 + add
        else:
            print('Ты не должен сюда попасть, но вдруг 1')
            return
        self.setFormat(start, ax, stile[i])
        self.current_g_cod_pool[self.count][i + 1] = nya.captured(n + 1)

    def nesting(self, n, nya, start, ax, stile):
        print('nesting s')
        add = 2
        symbol = nya.captured(n)
        if symbol == 'X':
            i = 1 + add
        elif symbol == 'Y':
            i = 2 + add
        elif symbol == 'Z':
            i = 3 + add
        elif symbol == 'C':
            i = 6 + add
        elif symbol == 'A':
            i = 4 + add
        elif symbol == 'B':
            i = 5 + add

        else:
            print('Ты не должен сюда попасть, но вдруг')
            return
        self.setFormat(start, ax, stile[i])
        self.current_g_cod_pool[self.count][i + 1] = nya.captured(n + 1)

    def to_the_start(self):
        self.standart_step = 1
        self.count = 0
        self.base.progress_bar.setMaximum(1)
        print("the end1")
示例#12
0
class SyntaxHighlighter(QSyntaxHighlighter):
    """
    Syntax highlighter for python
    """
    def __init__(self, parent: QTextDocument = None, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        # private members
        self._comment_start_expression = None
        self._comment_end_expression = None
        self._keyword_format = QTextCharFormat()
        self._class_format = QTextCharFormat()
        self._single_line_comment_format = QTextCharFormat()
        self._multi_line_comment_format = QTextCharFormat()
        self._quotation_format = QTextCharFormat()
        self._function_format = QTextCharFormat()
        self._highlighting_rules = list()

        # highlighting rules
        self._keyword_format.setForeground(Qt.darkBlue)
        self._keyword_format.setFontWeight(QFont.Bold)

        keywords = [
            'class', 'def', 'return'
            'self', 'float', 'int', 'list', 'dict', 'if', 'else', 'elif',
            'pass', 'None', 'object', 'for', 'while', 'is', 'in', 'print',
            'round', 'min', 'max', 'abs', 'lambda', 'import', 'as', 'from',
            'and', 'or'
        ]
        keyword_patterns = ['\\b{}\\b'.format(keyword) for keyword in keywords]

        for pattern in keyword_patterns:
            rule = HighlightingRule()
            rule.pattern = QRegularExpression(pattern)
            rule.format = self._keyword_format
            self._highlighting_rules.append(rule)

        self._class_format.setFontWeight(QFont.Bold)
        self._class_format.setForeground(Qt.darkMagenta)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression('\\bQ[A-Za-z+\\b]')
        rule.format = self._class_format
        self._highlighting_rules.append(rule)

        self._quotation_format.setFontWeight(QFont.Bold)
        self._quotation_format.setForeground(Qt.darkGreen)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression('".*"')
        rule.format = self._quotation_format
        self._highlighting_rules.append(rule)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression("'.*'")
        rule.format = self._quotation_format
        self._highlighting_rules.append(rule)

        self._function_format.setForeground(Qt.blue)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression('\\b[A-Za-z0-9_]+(?=\\())')
        rule.format = self._function_format
        self._highlighting_rules.append(rule)

        self._single_line_comment_format.setForeground(Qt.gray)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression('#[^\n]*')
        rule.format = self._single_line_comment_format
        self._highlighting_rules.append(rule)

        self._multi_line_comment_format.setForeground(Qt.gray)
        self._comment_start_expression = QRegularExpression('"""*')
        self._comment_end_expression = QRegularExpression('*"""')

    def highlightBlock(self, p_str):
        for rule in self._highlighting_rules:
            match_iterator = rule.pattern.globalMatch(p_str)
            while match_iterator.hasNext():
                match = match_iterator.next()
                self.setFormat(match.capturedStart(), match.capturedLength(),
                               rule.format)
        self.setCurrentBlockState(0)

        start_index = 0
        if self.previousBlockState() != 1:
            start_index = index_in_str(
                p_str, self._comment_start_expression.pattern())

        while start_index >= 0:
            match = self._comment_end_expression.match(p_str, start_index)
            end_index = match.capturedStart()
            comment_length = 0
            if end_index == -1:
                self.setCurrentBlockState(1)
                comment_length = len(p_str) - start_index
            else:
                comment_length = end_index - start_index + match.capturedLength(
                )
            self.setFormat(start_index, comment_length,
                           self._multi_line_comment_format)
            start_index = index_in_str(
                p_str, self._comment_start_expression.pattern(),
                start_index + comment_length)
示例#13
0
class PythonHighlighter(QSyntaxHighlighter):

    KEYWORDS = [
        'False', 'def', 'if', 'raise', 'None', 'del', 'import', 'return',
        'True', 'elif', 'in', 'try', 'and', 'else', 'is', 'while', 'as',
        'except', 'lambda', 'with', 'assert', 'finally', 'nonlocal', 'yield',
        'break', 'for', 'not', 'class', 'from', 'or', 'continue', 'global',
        'pass'
    ]

    OPERATORS = [
        '=',
        # Comparison
        '==',
        '!=',
        '<',
        '<=',
        '>',
        '>=',
        # Arithmetic
        '\+',
        '-',
        '\*',
        '/',
        '//',
        '\%',
        '\*\*',
        # In-place
        '\+=',
        '-=',
        '\*=',
        '/=',
        '\%=',
        # Bitwise
        '\^',
        '\|',
        '\&',
        '\~',
        '>>',
        '<<',
    ]

    BRACES = ['\{', '\}', '\(', '\)', '\[', '\]']

    def __init__(self, document):

        QSyntaxHighlighter.__init__(self, document)

        rules = []

        # These are the defaults rules
        rules += [(r'\b%s\b' % kw, 0, STYLES["keyword"])
                  for kw in PythonHighlighter.KEYWORDS]
        rules += [(r'%s' % o, 0, STYLES["operator"])
                  for o in PythonHighlighter.OPERATORS]
        rules += [(r'%s' % b, 0, STYLES["brace"])
                  for b in PythonHighlighter.BRACES]

        # All other rules
        rules += [
            # 'self'
            (r'\bself\b', 0, STYLES['self']),

            # Double-quoted string, possibly containing escape sequences
            (r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']),
            # Single-quoted string, possibly containing escape sequences
            (r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']),

            # 'def' followed by an identifier
            (r'\bdef\b\s*(\w+)', 1, STYLES['defclass']),
            # 'class' followed by an identifier
            (r'\bclass\b\s*(\w+)', 1, STYLES['defclass']),

            # From '#' until a newline
            (r'#[^\n]*', 0, STYLES['comment']),

            # Numeric literals
            (r'\b[+-]?[0-9]+[lL]?\b', 0, STYLES['numbers']),
            (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, STYLES['numbers']),
            (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0,
             STYLES['numbers']),
        ]

        self.rules = [(QRegExp(pat), index, fmt)
                      for (pat, index, fmt) in rules]

        self.multiline_end = QRegExp(r'"""')
        self.multiline_start = QRegExp(r'"""')

    def highlightBlock(self, text):
        """Apply highlight"""

        # expression is a QRegularExpression
        # Nth is the index of the matched thing
        for expression, nth, fmt in self.rules:
            matchIter = expression.globalMatch(text)
            while matchIter.hasNext():
                match = matchIter.next()
                self.setFormat(match.capturedStart(nth),
                               match.capturedLength(nth), fmt)

        self.setCurrentBlockState(0)

        startIndex = 0
        if (self.previousBlockState() != 1):
            startIndex = self.multiline_start.match(text).capturedStart()

        while (startIndex >= 0):
            # print(dir(self.multiline_end))
            match = self.multiline_end.match(text, startIndex)
            endIndex = match.capturedStart()
            commentLength = 0
            if (endIndex == -1):
                self.setCurrentBlockState(1)
                commentLength = text.length() - startIndex
            else:
                commentLength = endIndex - startIndex + match.capturedLength()
            self.setFormat(startIndex, commentLength, STYLES["string2"])
            startIndex = self.multiline_start.match(
                text, startIndex + commentLength).capturedStart()
示例#14
0
class CxxHighlighter(QSyntaxHighlighter):
    def __init__(self, parent):
        super().__init__(parent)

        self.rules = []

        keywordFormat = QTextCharFormat()
        keywordFormat.setForeground(QColor("#0016ba"))
        keywordFormat.setFontWeight(QFont.Bold)
        keywordPatterns = [
            "\\bchar\\b",
            "\\bclass\\b",
            "\\bconst\\b",
            "\\bdouble\\b",
            "\\benum\\b",
            "\\bexplicit\\b",
            "\\bfriend\\b",
            "\\binline\\b",
            "\\bint\\b",
            "\\blong\\b",
            "\\bnamespace\\b",
            "\\boperator\\b",
            "\\bprivate\\b",
            "\\bprotected\\b",
            "\\bpublic\\b",
            "\\bshort\\b",
            "\\bsignals\\b",
            "\\bsigned\\b",
            "\\bslots\\b",
            "\\bstatic\\b",
            "\\bstruct\\b",
            "\\btemplate\\b",
            "\\btypedef\\b",
            "\\btypename\\b",
            "\\bunion\\b",
            "\\bunsigned\\b",
            "\\bvirtual\\b",
            "\\bvoid\\b",
            "\\bvolatile\\b",
            "\\bbool\\b",
            "\\bchar8_t\\b",
            "\\bchar16_t\\b",
            "\\bchar32_t\\b",
        ]

        for pattern in keywordPatterns:
            rule = {
                'pattern': QRegularExpression(pattern),
                'format': keywordFormat
            }
            self.rules.append(rule)

        keyword2Format = QTextCharFormat()
        keyword2Format.setForeground(QColor("#0016ba"))
        keyword2Format.setFontWeight(QFont.Bold)
        keyword2Patterns = [
            "\\balignas\\b",
            "\\balignof\\b",
            "\\band\\b",
            "\\band_eq\\b",
            "\\basm\\b",
            "\\batomic_cancel\\b",
            "\\batomic_commit\\b",
            "\\batomic_noexcept\\b",
            "\\bauto\\b",
            "\\bbitand\\b",
            "\\bbitor\\b",
            "\\bbreak\\b",
            "\\bcase\\b",
            "\\bcatch\\b",
            "\\bcompl\\b",
            "\\bconcept\\b",
            "\\bconsteval\\b",
            "\\bconstexpr\\b",
            "\\bconstinit\\b",
            "\\bconst_cast\\b",
            "\\bcontinue\\b",
            "\\bco_await\\b",
            "\\bco_return\\b",
            "\\bco_yield\\b",
            "\\bdecltype\\b",
            "\\bdefault\\b",
        ]

        for pattern in keyword2Patterns:
            rule = {
                'pattern': QRegularExpression(pattern),
                'format': keyword2Format
            }
            self.rules.append(rule)

        classFormat = QTextCharFormat()
        classFormat.setFontWeight(QFont.Bold)
        classFormat.setForeground(Qt.darkMagenta)
        rule = {
            'pattern': QRegularExpression("\\bQ[A-Za-z]+\\b"),
            'format': classFormat
        }
        self.rules.append(rule)

        quotationFormat = QTextCharFormat()
        quotationFormat.setForeground(QColor("#c90000"))
        rule = {
            'pattern': QRegularExpression("\".*\""),
            'format': quotationFormat
        }
        self.rules.append(rule)

        directiveFormat = QTextCharFormat()
        directiveFormat.setForeground(QColor("#c95508"))
        rule = {
            'pattern': QRegularExpression("#.*"),
            'format': directiveFormat
        }
        self.rules.append(rule)

        stdFormat = QTextCharFormat()
        stdFormat.setForeground(QColor("#8c8c8c"))
        rule = {
            'pattern': QRegularExpression("std::[A-Za-z]+"),
            'format': stdFormat
        }
        self.rules.append(rule)

        # functionFormat = QTextCharFormat()
        # functionFormat.setForeground(Qt.blue)
        # rule = {'pattern':QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()"),
        #         'format':functionFormat}
        # self.rules.append(rule)

        singleLineCommentFormat = QTextCharFormat()
        singleLineCommentFormat.setForeground(Qt.darkGreen)
        rule = {
            'pattern': QRegularExpression("//[^\n]*"),
            'format': singleLineCommentFormat
        }
        self.rules.append(rule)

        self.multiLineCommentFormat = QTextCharFormat()
        self.multiLineCommentFormat.setForeground(Qt.red)
        self.commentStartExpression = QRegularExpression("/\\*")
        self.commentEndExpression = QRegularExpression("\\*/")

    def highlightBlock(self, text):

        for rule in self.rules:
            matchIter = rule['pattern'].globalMatch(text)

            while matchIter.hasNext():
                match = matchIter.next()
                self.setFormat(match.capturedStart(), match.capturedLength(),
                               rule['format'])

        self.setCurrentBlockState(0)

        startIdx = 0
        if self.previousBlockState() != 1:
            startIdx = text.find(self.commentStartExpression.pattern())

        while startIdx >= 0:

            match = self.commentEndExpression.match(text, startIdx)
            endIdx = match.capturedStart()
            commentLength = 0
            if endIdx == -1:
                self.setCurrentBlockState(1)
                commentLength = len(text) - startIdx
            else:
                commentLength = endIdx - startIdx + match.capturedLength()
            self.setFormat(startIdx, commentLength,
                           self.multiLineCommentFormat)
            startIdx = text.find(self.commentStartExpression.pattern(),
                                 start=startIdx + commentLength)