///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2020 Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RiuQssSyntaxHighlighter.h" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QssSyntaxHighligter::QssSyntaxHighligter( QTextDocument* parent ) : QSyntaxHighlighter( parent ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void QssSyntaxHighligter::highlightBlock( const QString& text ) { QTextCharFormat variableFormat; variableFormat.setFontWeight( QFont::Bold ); variableFormat.setForeground( QColor( "#e20a48" ) ); QTextCharFormat commentFormat; commentFormat.setFontWeight( QFont::Normal ); commentFormat.setForeground( QColor( "#4e9041" ) ); QTextCharFormat classFormat; classFormat.setFontWeight( QFont::Bold ); classFormat.setForeground( QColor( "#fc8f00" ) ); QTextCharFormat handleFormat; handleFormat.setFontWeight( QFont::Bold ); handleFormat.setForeground( QColor( "#e20a48" ) ); QTextCharFormat modifierFormat; modifierFormat.setFontWeight( QFont::Normal ); modifierFormat.setForeground( QColor( "#e20a48" ) ); // Block states: // -1 - none // 1 - inside class // 2 - inside function // 3 - inside multiline comment QRegularExpression classStartExpression = QRegularExpression( QString( "\\{" ) ); QRegularExpression classEndExpression = QRegularExpression( QString( "\\}" ) ); QRegularExpression functionStartExpression = QRegularExpression( QString( "\\(" ) ); QRegularExpression functionEndExpression = QRegularExpression( QString( "\\)" ) ); QRegularExpression commentStartExpression = QRegularExpression( QString( "/\\*" ) ); QRegularExpression commentEndExpression = QRegularExpression( QString( "\\*/" ) ); setCurrentBlockState( -1 ); auto parseClass = [this, text]( int startIndex, int length ) { QTextCharFormat propertyFormat; propertyFormat.setFontWeight( QFont::Bold ); QTextCharFormat valueFormat; valueFormat.setFontWeight( QFont::Normal ); valueFormat.setForeground( QColor( "#0d98ce" ) ); QTextCharFormat functionFormat; functionFormat.setFontWeight( QFont::Bold ); functionFormat.setForeground( QColor( "#dd1bc1" ) ); QRegularExpression expression = QRegularExpression( "\\s*([a-zA-Z0-9_-]+)[ \\t]*:\\s*([a-zA-Z0-9_-]+\\()?([\\$#\\[\\]:\\.,a-zA-Z0-9-_ " "]+)(\\))?[ \\t]*;" ); QRegularExpressionMatchIterator j = expression.globalMatch( text ); while ( j.hasNext() ) { QRegularExpressionMatch matchClass = j.next(); setFormat( startIndex + matchClass.capturedStart( 1 ), matchClass.capturedLength( 1 ), propertyFormat ); setFormat( startIndex + matchClass.capturedStart( 2 ), matchClass.capturedLength( 2 ), functionFormat ); setFormat( startIndex + matchClass.capturedStart( 3 ), matchClass.capturedLength( 3 ), valueFormat ); setFormat( startIndex + matchClass.capturedStart( 4 ), matchClass.capturedLength( 4 ), functionFormat ); } }; if ( previousBlockState() == -1 ) { QRegularExpression expression = QRegularExpression( "([a-zA-z0-9_-]+)(::[a-zA-Z0-9_-]+)?(:[a-zA-Z0-9_-]+)?" ); QRegularExpressionMatchIterator i = expression.globalMatch( text ); while ( i.hasNext() ) { QRegularExpressionMatch matchClass = i.next(); setFormat( matchClass.capturedStart( 1 ), matchClass.capturedLength( 1 ), classFormat ); setFormat( matchClass.capturedStart( 2 ), matchClass.capturedLength( 2 ), handleFormat ); setFormat( matchClass.capturedStart( 3 ), matchClass.capturedLength( 3 ), modifierFormat ); } int startIndex = text.indexOf( classStartExpression ); while ( startIndex >= 0 ) { QRegularExpressionMatch match = classEndExpression.match( text, startIndex ); int endIndex = match.capturedStart(); int classLength = 0; if ( endIndex == -1 ) { setCurrentBlockState( 1 ); classLength = text.length() - startIndex; } else { classLength = endIndex - startIndex + match.capturedLength(); } parseClass( startIndex, classLength ); startIndex = text.indexOf( classStartExpression, startIndex + classLength ); } } if ( previousBlockState() == 1 ) { int startIndex = 0; while ( startIndex >= 0 ) { QRegularExpressionMatch match = classEndExpression.match( text, startIndex ); int endIndex = match.capturedStart(); int classLength = 0; if ( endIndex == -1 ) { setCurrentBlockState( 1 ); classLength = text.length() - startIndex; } else { classLength = endIndex - startIndex + match.capturedLength(); } parseClass( startIndex, classLength ); startIndex = text.indexOf( classStartExpression, startIndex + classLength ); } } QRegularExpression expression( "\\$[a-zA-z0-9_]+" ); QRegularExpressionMatchIterator i = expression.globalMatch( text ); while ( i.hasNext() ) { QRegularExpressionMatch match = i.next(); setFormat( match.capturedStart(), match.capturedLength(), variableFormat ); } expression = QRegularExpression( "\\/\\/(.*)" ); i = expression.globalMatch( text ); while ( i.hasNext() ) { QRegularExpressionMatch match = i.next(); setFormat( match.capturedStart(), match.capturedLength(), commentFormat ); } int startIndex = 0; if ( previousBlockState() != 2 ) startIndex = text.indexOf( commentStartExpression ); while ( startIndex >= 0 ) { QRegularExpressionMatch match = commentEndExpression.match( text, startIndex ); int endIndex = match.capturedStart(); int commentLength = 0; if ( endIndex == -1 ) { setCurrentBlockState( 2 ); commentLength = text.length() - startIndex; } else { commentLength = endIndex - startIndex + match.capturedLength(); } setFormat( startIndex, commentLength, commentFormat ); startIndex = text.indexOf( commentStartExpression, startIndex + commentLength ); } }