ceditor/include/utils/SyntaxHighlighter.h
2024-12-20 16:29:18 +08:00

62 lines
1.9 KiB
C++

#ifndef SYNTAX_HIGHLIGHTER_H
#define SYNTAX_HIGHLIGHTER_H
#include "Color.h"
#include "RichText.h"
#include <string>
#include "../mystl/my_vector.h"
#include <fstream>
#include "LexicalAnalysis.h"
struct HighlightRule {
CodeTokenType type;
MColor color;
};
class SyntaxHighlighter {
private:
std::string ruleName;
MyVector<HighlightRule> rules;
public:
SyntaxHighlighter(std::string ruleName) {
this->ruleName = ruleName;
// std::ifstream file("../data/highlight/" + ruleName + "/rules.txt"); // Just for unit test
std::ifstream file("./data/highlight/" + ruleName + "/rules.txt");
if (file.is_open()) {
// printf("keywords file open\n");
std::string line;
while (std::getline(file, line)) {
//every line is like "ruleName(string):color(short)"
CodeTokenType type = stringToCodeTokenType(line.substr(0, line.find(":")));
MColor color = static_cast<MColor>(std::stoi(line.substr(line.find(":") + 1)));
rules.push_back(HighlightRule{type, color});
}
file.close();
}
}
RichText highlight(std::string text) {
LexicalAnalysis lexicalAnalysis(this->ruleName);
lexicalAnalysis.setRawText(text);
MyVector<Token> tokens = lexicalAnalysis.tokenize();
RichText richText;
for (int i = 0; i < tokens.size(); i++) {
Token token = tokens[i];
bool hasMatched = false;
for (int j = 0; j < rules.size(); j++) {
HighlightRule rule = rules[j];
if (token.type == rule.type) {
hasMatched = true;
richText += RichText(token.value, rule.color);
}
}
if (!hasMatched) {
richText += RichText(token.value, COLOR_WHITE);
}
}
return richText;
}
};
#endif // SYNTAX_HIGHLIGHTER_H