File indexing completed on 2022-11-29 18:16:32

0001 /*
0002     SPDX-FileCopyrightText: 2003-2006 Cies Breijs <cies AT kde DOT nl>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "highlighter.h"
0008 
0009 
0010 
0011 Highlighter::Highlighter(QTextDocument *parent)
0012     : QSyntaxHighlighter(parent)
0013 {
0014     variableFormat.setFontWeight(QFont::Bold);
0015     variableFormat.setForeground(Qt::darkMagenta);
0016 
0017     trueFalseFormat.setForeground(Qt::darkRed);
0018 
0019     numberFormat.setForeground(Qt::darkRed);
0020 
0021     commentFormat.setForeground(Qt::gray);
0022 
0023     scopeFormat.setFontWeight(QFont::Bold);
0024     scopeFormat.setForeground(Qt::darkGreen);
0025 
0026     stringFormat.setForeground(Qt::red);
0027 
0028     controllerCommandFormat.setFontWeight(QFont::Bold);
0029     controllerCommandFormat.setForeground(Qt::black);
0030 
0031     otherCommandFormat.setForeground(Qt::darkBlue);
0032 
0033     learnCommandFormat.setFontWeight(QFont::Bold);
0034     learnCommandFormat.setForeground(Qt::green);
0035 
0036     booleanOperatorFormat.setFontWeight(QFont::Bold);
0037     booleanOperatorFormat.setForeground(QColor(255, 90, 255));  // pink
0038 
0039     expressionFormat.setFontWeight(QFont::Bold);
0040     expressionFormat.setForeground(QColor(90, 100, 255));  // light blue
0041 
0042     mathOperatorFormat.setFontWeight(QFont::Bold);
0043     mathOperatorFormat.setForeground(Qt::darkGray);
0044 
0045     assignmentFormat.setFontWeight(QFont::Bold);
0046     assignmentFormat.setForeground(Qt::black);
0047 
0048     tokenizer = new Tokenizer();
0049 }
0050 
0051 Highlighter::~Highlighter()
0052 {
0053     delete tokenizer;
0054 }
0055 
0056 
0057 QTextCharFormat* Highlighter::formatForStatement(const QString &text)
0058 {
0059     // TODO store the Token (pointer) in the respective inspector lists so we don't have to re-tokenize here...
0060     tokenizer->initialize(text);
0061     return tokenToFormat(tokenizer->getToken());
0062 }
0063 
0064 Token* Highlighter::checkOrApplyHighlighting(const QString& text, int cursorIndex)
0065 {
0066     tokenizer->initialize(text);
0067     Token* token = tokenizer->getToken();
0068     QTextCharFormat* format;
0069     while (token->type() != Token::EndOfInput) {
0070         format = tokenToFormat(token);
0071         if (format) {
0072             if (cursorIndex == -1)  // does not return, but keeps running
0073                 setFormat(token->startCol() - 1, token->endCol() - token->startCol(), *format);
0074             else if (cursorIndex >= token->startCol() && cursorIndex <= token->endCol())
0075                 return token;  // returns, one shot only
0076         }
0077         delete token;
0078         token = tokenizer->getToken();
0079     }
0080     delete token;
0081     return nullptr;
0082 }
0083 
0084 QTextCharFormat* Highlighter::tokenToFormat(Token* token)
0085 {
0086     switch (token->category()) {
0087         case Token::VariableCategory:          return &variableFormat;
0088         case Token::TrueFalseCategory:         return &trueFalseFormat;
0089         case Token::NumberCategory:            return &numberFormat;
0090         case Token::CommentCategory:           return &commentFormat;
0091         case Token::StringCategory:            return &stringFormat;
0092         case Token::ScopeCategory:             return &scopeFormat;
0093         case Token::CommandCategory:           return &otherCommandFormat;
0094         case Token::ControllerCommandCategory: return &controllerCommandFormat;
0095         case Token::LearnCommandCategory:      return &learnCommandFormat;
0096         case Token::ExpressionCategory:        return &expressionFormat;
0097         case Token::BooleanOperatorCategory:   return &booleanOperatorFormat;
0098         case Token::MathOperatorCategory:      return &mathOperatorFormat;
0099         case Token::AssignmentCategory:        return &assignmentFormat;
0100 
0101         // do nothing with these...
0102         case Token::ParenthesisCategory:       return nullptr;
0103         case Token::FunctionCallCategory:      return nullptr;
0104         case Token::ArgumentSeparatorCategory: return nullptr;
0105     }
0106     return nullptr;
0107 }