XML To FastInfoset Converter Example

from DevMachines import __pyside2__, __pyside6__

if __pyside2__:
    from PySide2 import QtCore
    from PySide2.QtCore import Qt, QRegularExpression
    from PySide2.QtGui import QSyntaxHighlighter, QTextCharFormat, QFont

if __pyside6__:
    from PySide6 import QtCore
    from PySide6.QtCore import Qt, QRegularExpression
    from PySide6.QtGui import QSyntaxHighlighter, QTextCharFormat, QFont

class HighlightingRule():
    def __init__(self):
        self.pattern = None
        self.format = None

class XmlSyntaxHighlighter(QSyntaxHighlighter):
    def __init__(self, parent):
        QSyntaxHighlighter.__init__(self, parent)

        self.highlightingRules = []
        self.tagFormat = QTextCharFormat()
        self.attributeFormat = QTextCharFormat()
        self.attributeContentFormat = QTextCharFormat()
        self.commentFormat = QTextCharFormat()

        # tag format
        self.tagFormat.setForeground(Qt.darkBlue)
        self.tagFormat.setFontWeight(QFont.Bold)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression("(<[a-zA-Z:\\-]+\\b|<\\?[a-zA-Z:\\-]+\\b|<\\![a-zA-Z:\\-]+\\b|\\?>|>|/>|</[a-zA-Z:\\-]+>)")
        rule.format = self.tagFormat
        self.highlightingRules.append(rule)

        # attribute format
        self.attributeFormat.setForeground(Qt.darkGreen)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression("[a-zA-Z:\\-]+=")
        rule.format = self.attributeFormat
        self.highlightingRules.append(rule)

        # attribute content format
        self.attributeContentFormat.setForeground(Qt.red)
        rule = HighlightingRule()
        rule.pattern = QRegularExpression("(\"[^\"]*\"|'[^']*')")
        rule.format = self.attributeContentFormat
        self.highlightingRules.append(rule)

        self.commentFormat.setForeground(Qt.lightGray)
        self.commentFormat.setFontItalic(True)

        self.commentStartExpression = QRegularExpression("<!--")
        self.commentEndExpression = QRegularExpression("-->")

    def highlightBlock(self, text):
        for rule in self.highlightingRules:
            expression = rule.pattern
            matchIterator = rule.pattern.globalMatch(text)
            while matchIterator.hasNext():
                match = matchIterator.next()
                self.setFormat(match.capturedStart(), match.capturedLength(), rule.format)

        self.setCurrentBlockState(0)

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

        while startIndex >= 0:
            match = self.commentEndExpression.match(text, startIndex)
            endIndex = match.capturedStart()
            commentLength = 0
            if endIndex == -1:
                self.setCurrentBlockState(1)
                commentLength = len(text) - startIndex
            else:
                commentLength = endIndex - startIndex + match.capturedLength()

            self.setFormat(startIndex, commentLength, self.commentFormat)
            startIndex = startIndex = self.commentStartExpression.match(text, startIndex + commentLength).capturedStart()