HAL
python_syntax_highlighter.cpp
Go to the documentation of this file.
2 
4 namespace hal
5 {
7  : QSyntaxHighlighter(parent), mMultiLineCommentDelimiter("('''|\"\"\")"), mTrippleSingleQuote("'''"), mTrippleDoubleQuote("\"\"\"")
8  // //mKeywordColor(177, 240, 0),
9  // //mKeywordColor("#ffd200"),
10  // mKeywordColor("#CC7832"),
11  // //mKeywordColor("#6419E6"),
12  // //mKeywordColor("#9019E6"),
13  // //mOperatorColor("#0A81FF"),
14  // mOperatorColor("#A9B7C6"), mBraceColor("#A9B7C6"), mDefclassColor("#A9B7C6"),
15  // //mSingleQuotedStringColor("#17de4c"),
16  // //mDoubleQuotedStringColor("#17de4c"),
17  // mSingleQuotedStringColor("#A5C25C"), mDoubleQuotedStringColor("#A5C25C"),
18  // mSelfColor("#A9B7C6"),
19  // //mNumberColor(236, 118, 0),
20  // //mNumberColor("#DB8000"),
21  // //mNumberColor("#89F406"),
22  // //mNumberColor("#F4EC06"),
23  // mNumberColor("#6897BB"),
24  // //mCommentColor("#6F7B7B")
25  // //mCommentColor(222, 233, 175)
26  // //mCommentColor("#556062")
27  // //mCommentColor("#30474B") //2.0
28  // //mCommentColor("#3A565A") //2.5
29  // mCommentColor("#629755") //2.98
30  {
31  HighlightingRule rule;
32 
33  rule.mPattern = QRegularExpression("\\b(and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|"
34  "nonlocal|not|or|pass|raise|return|try|while|with|yield|False|None|True)\\b");
35  rule.mPattern.optimize();
37  mHighlightingRules.append(rule);
38 
39  rule.mPattern = QRegularExpression("=|==|!=|<|<=|>|>=|\\+|-|\\*|/|//|%|\\*\\*|\\+=|-=|\\*=|/=|%=|\\^|\\||&|~|>>|<<");
40  rule.mPattern.optimize();
42  mHighlightingRules.append(rule);
43 
44  rule.mPattern = QRegularExpression("{|}|\\(|\\)|\\[|]");
45  rule.mPattern.optimize();
46  rule.mFormat = PythonQssAdapter::instance()->mBraceFormat;
47  mHighlightingRules.append(rule);
48 
49  rule.mPattern = QRegularExpression("'[^']*'");
50  rule.mPattern.optimize();
52  mHighlightingRules.append(rule);
53 
54  rule.mPattern = QRegularExpression("\"[^\"]*\"");
55  rule.mPattern.optimize();
57  mHighlightingRules.append(rule);
58 
59  rule.mPattern = QRegularExpression("\\bself\\b");
60  rule.mPattern.optimize();
61  rule.mFormat = PythonQssAdapter::instance()->mSelfFormat;
62  mHighlightingRules.append(rule);
63 
64  rule.mPattern = QRegularExpression("(\\b([1-9][0-9]*|0)[.]?[0-9]*[eE][+-]?[0-9]+[jJ]?\\b)|"// Exponent float
65  "(\\b([1-9][0-9]*|0)\\.[0-9]*[jJ]?)|" // Point float
66  "(\\b0[xX][0-9A-Fa-f]+[lL]?\\b)|" // Hexadecimal integer
67  "(\\b0[oO][0-7]+[lL]?\\b)|" // Octal integer
68  "(\\b([1-9][0-9]*|0)[lLjJ]?\\b)"); // Decimal integer
69 
70  rule.mPattern.optimize();
71  rule.mFormat = PythonQssAdapter::instance()->mNumberFormat;
72  mHighlightingRules.append(rule);
73 
74  rule.mPattern = QRegularExpression("#[^\\n]*");
75  rule.mPattern.optimize();
77  mHighlightingRules.append(rule);
78  }
79 
81  {
82  for (const HighlightingRule& rule : mHighlightingRules)
83  {
84  QRegularExpressionMatchIterator it = rule.mPattern.globalMatch(text);
85  while (it.hasNext())
86  {
87  QRegularExpressionMatch match = it.next();
88  int index = match.capturedStart();
89  int length = match.capturedLength();
90  setFormat(index, length, rule.mFormat);
91  }
92  }
93 
94  // 0 no open comment in block
95  // 1 contains tripple single quote start and no tripple single quote end OR follows a "1" block and also doesnt contain the end
96  // 2 contains tripple double quote start and no tripple double quote end OR follows a "2" block and also doesnt contain the end
97 
98  int current_index = 0;
99 
100  if (previousBlockState() == 1)
101  {
102  current_index = closeMultilineComment(text, mTrippleSingleQuote);
103 
104  if (current_index < 0)
105  {
107  return;
108  }
109  }
110 
111  if (previousBlockState() == 2)
112  {
113  current_index = closeMultilineComment(text, mTrippleDoubleQuote);
114 
115  if (current_index < 0)
116  {
118  return;
119  }
120  }
121 
122  QRegularExpressionMatch match = mMultiLineCommentDelimiter.match(text, current_index);
123 
124  while (match.hasMatch())
125  {
126  // check which delimiter was found
127  // check for closing delimiter
128  // found -> loop again
129  // not found -> set block state and return
130 
131  int comment_start_index = match.capturedStart();
132  QChar comment_type = text.at(comment_start_index);
133 
134  if (comment_type == '\'')
135  {
136  QRegularExpressionMatch single_match = mTrippleSingleQuote.match(text, comment_start_index + 3);
137  int single_match_index = single_match.capturedStart();
138 
139  if (single_match_index < 0)
140  {
142  setFormat(comment_start_index, text.length() - comment_start_index, PythonQssAdapter::instance()->mCommentFormat);
143  return;
144  }
145  else
146  {
147  setFormat(comment_start_index, comment_start_index - single_match_index + 3, PythonQssAdapter::instance()->mCommentFormat);
148  match = mMultiLineCommentDelimiter.match(text, single_match_index + 3);
149  }
150  }
151  else
152  {
153  QRegularExpressionMatch double_match = mTrippleDoubleQuote.match(text, comment_start_index + 3);
154  int double_match_index = double_match.capturedStart();
155 
156  if (double_match_index < 0)
157  {
159  setFormat(comment_start_index, text.length() - comment_start_index, PythonQssAdapter::instance()->mCommentFormat);
160  return;
161  }
162  else
163  {
164  setFormat(comment_start_index, comment_start_index - double_match_index + 3, PythonQssAdapter::instance()->mCommentFormat);
165  match = mMultiLineCommentDelimiter.match(text, double_match_index + 3);
166  }
167  }
168  }
170  return;
171  }
172 
173  int PythonSyntaxHighlighter::closeMultilineComment(const QString& text, const QRegularExpression& delimiter, const int offset)
174  {
175  QRegularExpressionMatch match = delimiter.match(text, offset);
176  int index = match.capturedEnd();
177 
178  if (index < 0)
179  setFormat(offset, text.length() - offset, PythonQssAdapter::instance()->mCommentFormat);
180  else
181  setFormat(offset, index - offset, PythonQssAdapter::instance()->mCommentFormat);
182 
183  return index;
184  }
185 }
static PythonQssAdapter * instance()
QTextCharFormat mBraceFormat
QTextCharFormat mNumberFormat
QTextCharFormat mSingleQuotedStringFormat
QTextCharFormat mCommentFormat
QTextCharFormat mDoubleQuotedStringFormat
QTextCharFormat mKeywordFormat
QTextCharFormat mOperatorFormat
QTextCharFormat mSelfFormat
PythonSyntaxHighlighter(QTextDocument *parent=nullptr)
void highlightBlock(const QString &text) override
QRegularExpressionMatch match(const QString &subject, int offset, QRegularExpression::MatchType matchType, QRegularExpression::MatchOptions matchOptions) const const
int capturedEnd(int nth) const const
int capturedLength(int nth) const const
int capturedStart(int nth) const const
bool hasMatch() const const
QRegularExpressionMatch next()
const QChar at(int position) const const
int length() const const
int previousBlockState() const const
void setCurrentBlockState(int newState)
void setFormat(int start, int count, const QTextCharFormat &format)
void append(const T &value)