src/ldrawsyntaxhighlighter.cpp

changeset 331
638a7458ef5e
child 342
9fd7dcab6d76
equal deleted inserted replaced
330:edb6c09cdd3c 331:638a7458ef5e
1 #include "ldrawsyntaxhighlighter.h"
2
3 #define NUMBER_REGEX R"([+-]?(?:(?:\d+\.?\d*)|(?:\.\d+)))"
4 #define SPACE_REGEX R"(\s+)"
5 #define VEC3_REGEX "(" NUMBER_REGEX SPACE_REGEX NUMBER_REGEX SPACE_REGEX NUMBER_REGEX ")"
6 #define TWO_VECTORS VEC3_REGEX SPACE_REGEX VEC3_REGEX
7 #define THREE_VECTORS TWO_VECTORS SPACE_REGEX VEC3_REGEX
8 #define FOUR_VECTORS THREE_VECTORS SPACE_REGEX VEC3_REGEX
9
10 LDrawSyntaxHighlighter::LDrawSyntaxHighlighter(QTextDocument* parent) :
11 QSyntaxHighlighter{parent}
12 {
13 this->lineTypeFormat.setFontWeight(QFont::Bold);
14 this->point1Format.setForeground(Qt::green);
15 this->point2Format.setForeground(Qt::yellow);
16 this->point3Format.setForeground(Qt::cyan);
17 this->point4Format.setForeground(Qt::magenta);
18 this->point2Format.setFontWeight(QFont::Bold);
19 this->point4Format.setFontWeight(QFont::Bold);
20 this->nameFormat.setFontItalic(true);
21 this->bfcFormat.setForeground(Qt::green);
22 this->bfcFormat.setFontWeight(QFont::Bold);
23 this->errorFormat.setUnderlineColor(Qt::yellow);
24 this->errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
25 this->refPattern = QRegularExpression{R"(^\s*(1)\s+(\d+)\s+)" FOUR_VECTORS SPACE_REGEX R"(([^ ]+)\s*$)"};
26 this->trianglePattern = QRegularExpression{R"(^\s*(3)\s+(\d+)\s+)" THREE_VECTORS R"(\s*$)"};
27 this->quadrilateralPattern = QRegularExpression{R"(^\s*(4)\s+(\d+)\s+)" FOUR_VECTORS R"(\s*$)"};
28 this->cedgePattern = QRegularExpression{R"(^\s*(5)\s+(\d+)\s+)" FOUR_VECTORS R"(\s*$)"};
29 this->bfcPattern = QRegularExpression{QStringLiteral(
30 R"(^\s*(0) (BFC (?:CERTIFY CCW|CERTIFY CW|NOCERTIFY|INVERTNEXT|CLIP|NOCLIP))\s*$)"
31 )};
32 this->commentPattern = QRegularExpression{R"(^\s*(0)\s+(.+)$)"};
33 }
34
35 void LDrawSyntaxHighlighter::highlightBlock(const QString& text)
36 {
37 bool matched = false;
38 const auto matchRegex = [&text, this, &matched](
39 const QRegularExpression& re,
40 const QVector<const QTextCharFormat*> formats
41 ){
42 if (not matched) {
43 QRegularExpressionMatch match = re.match(text);
44 if (match.hasMatch()) {
45 for (int i = 0; i < formats.size(); ++i) {
46 this->setFormat(match.capturedStart(i + 1), match.capturedLength(i + 1), *formats[i]);
47 }
48 }
49 matched = match.hasMatch();
50 }
51 };
52 matchRegex(this->refPattern, {
53 &this->lineTypeFormat,
54 &this->colorFormat,
55 &this->point1Format,
56 &this->point2Format,
57 &this->point3Format,
58 &this->point4Format,
59 &this->nameFormat,
60 });
61 matchRegex(this->trianglePattern, {
62 &this->lineTypeFormat,
63 &this->colorFormat,
64 &this->point1Format,
65 &this->point2Format,
66 &this->point3Format,
67 });
68 matchRegex(this->quadrilateralPattern, {
69 &this->lineTypeFormat,
70 &this->colorFormat,
71 &this->point1Format,
72 &this->point2Format,
73 &this->point3Format,
74 &this->point4Format,
75 });
76 matchRegex(this->cedgePattern, {
77 &this->lineTypeFormat,
78 &this->colorFormat,
79 &this->point1Format,
80 &this->point2Format,
81 &this->point3Format,
82 &this->point4Format,
83 });
84 matchRegex(this->commentPattern, {
85 &this->lineTypeFormat,
86 &this->nameFormat,
87 });
88 matchRegex(this->bfcPattern, {
89 &this->lineTypeFormat,
90 &this->bfcFormat,
91 });
92 if (not matched) {
93 this->setFormat(0, text.length(), this->errorFormat);
94 }
95 }

mercurial