PDA

View Full Version : Highlight with two different syntaxes with QSyntaxHighlighter



codemonkey
8th November 2009, 21:20
Hello.

I have a working class that highlights fine right now.
Straight from the docs


void myClass::highlightBlock(const QString &text)
{
int length ;
int index = text.indexOf(this->m_pattern);
while (index >= 0)
{
length = this->m_pattern.matchedLength();
setFormat(index, length, this->m_format);
index = text.indexOf(this->m_pattern, index + length);
}
}


But now I wish to add another pattern and highlight with that. So I wonder how one should do this: Something like this?



void myClass::highlightBlock(const QString &text)
{
int index,index2,length;
index = text.indexOf(this->m_pattern);
index2 = text.indexOf(this->m_pattern2);
while (index >= 0 && index2 >=0)
{
if (index2 < index && index2>0=0)
{
length = this->m_pattern2.matchedLength();
setFormat(index, length, this->m_format2);
}
else if (index < index2 && index>=0)
{
length = this->m_pattern.matchedLength();
setFormat(index, length, this->m_format);
}

// perhaps some clever check to see that the matches do not overlap

index = text.indexOf(this->m_pattern, index + length);
index = text.indexOf(this->m_pattern2, index + length);
}
}


Will this work?

And how do you do really do this if one would write an editor with proper syntax highlighting for a language for example c++, how do you separate all the different kind of patterns to highlight with different formats?

lasher
8th November 2009, 21:50
Hi,

Please check syntaxhighlighter example from Qt, It shows how to make
syntax highlighting for C++. It's not perfect example because highlighting
doesn't work well, but you will understand how to add many highligh rules.


Regards

JohannesMunk
9th November 2009, 17:40
Maybe this will help you! I have pimped the syntaxhighlighter example a bit:

Now the rules have names, so that you can add/replace a search-highlight rule with varying patterns. The map returns the rules sorted by keys. The order is relevant because for example strings in comments or function calls in comments should not be highlighted..

Header-File:


#ifndef SYNTAXHIGHLIGHTER_H #define SYNTAXHIGHLIGHTER_H
#include <QSyntaxHighlighter>
#include <QTextCharFormat>
QT_BEGIN_NAMESPACE
class QTextDocument;
QT_END_NAMESPACE
class Highlighter : public QSyntaxHighlighter
{ Q_OBJECT
public:
Highlighter(QTextDocument *parent = 0);
void SetRule(QString name,QString pattern,QTextCharFormat format);
protected:
void highlightBlock(const QString &text);
struct HighlightingRule
{
HighlightingRule() {}
HighlightingRule(QRegExp _pattern,QTextCharFormat _format) {pattern = _pattern;format = _format;}
QRegExp pattern;
QTextCharFormat format;
};
QMap<QString,HighlightingRule> highlightingRules;
};
class MultiLineCommentHighlighter : public Highlighter
{ Q_OBJECT
public:
MultiLineCommentHighlighter(QTextDocument *parent = 0);
protected:
void highlightBlock(const QString &text);
QRegExp commentStartExpression;
QRegExp commentEndExpression;
QTextCharFormat multiLineCommentFormat;
};
class CppHighlighter : public MultiLineCommentHighlighter
{ Q_OBJECT
public:
CppHighlighter(QTextDocument *parent = 0);
};
#endif // SYNTAXHIGHLIGHTER_H
SyntaxHighlighter.cpp:

#include "SyntaxHighlighter.h" #include <QtGui>
/************************************************** **************************************
************************************************** **************************************
**** Highlighter ************************************************** *********************
************************************************** **************************************
************************************************** **************************************/
Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
{
}
void Highlighter::SetRule(QString name,QString pattern,QTextCharFormat format)
{
if (pattern != "")
highlightingRules.insert(name,HighlightingRule(QRe gExp(pattern),format));
else
highlightingRules.remove(name);
rehighlight();
}
void Highlighter::highlightBlock(const QString &text)
{
foreach (const HighlightingRule &rule, highlightingRules) {
QRegExp expression(rule.pattern);
int index = expression.indexIn(text);
while (index >= 0) {
int length = expression.matchedLength();
setFormat(index, length, rule.format);
index = expression.indexIn(text, index + length);
}
}
setCurrentBlockState(0);
}
/************************************************** **************************************
************************************************** **************************************
**** MultiLineCommentHighlighter ************************************************** *****
************************************************** **************************************
************************************************** **************************************/
MultiLineCommentHighlighter::MultiLineCommentHighl ighter(QTextDocument *parent) : Highlighter(parent)
{
multiLineCommentFormat.setForeground(Qt::red);
commentStartExpression = QRegExp("/\\*");
commentEndExpression = QRegExp("\\*/");
}
void MultiLineCommentHighlighter::highlightBlock(const QString &text)
{
Highlighter::highlightBlock(text);
int startIndex = 0;
if (previousBlockState() != 1)
startIndex = commentStartExpression.indexIn(text);
while (startIndex >= 0) {
int endIndex = commentEndExpression.indexIn(text, startIndex);
int commentLength;
if (endIndex == -1) {
setCurrentBlockState(1);
commentLength = text.length() - startIndex;
} else {
commentLength = endIndex - startIndex
+ commentEndExpression.matchedLength();
}
setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
}
}
/************************************************** **************************************
************************************************** **************************************
**** CppHighlighter ************************************************** ******************
************************************************** **************************************
************************************************** **************************************/
CppHighlighter::CppHighlighter(QTextDocument *parent) : MultiLineCommentHighlighter(parent)
{
QTextCharFormat keywordFormat;
QTextCharFormat classFormat;
QTextCharFormat singleLineCommentFormat;
QTextCharFormat quotationFormat;
QTextCharFormat functionFormat;
keywordFormat.setForeground(Qt::darkBlue);
keywordFormat.setFontWeight(QFont::Bold);
QStringList keywordPatterns;
keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b"
<< "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b"
<< "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b"
<< "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b"
<< "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b"
<< "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b"
<< "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
<< "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
<< "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
<< "\\bvoid\\b" << "\\bvolatile\\b";
int i = 0;
foreach (const QString &pattern, keywordPatterns) {
SetRule(QString("00_KeyWord_%1").arg(i),pattern,keywordFormat);
++i;
}
classFormat.setFontWeight(QFont::Bold);
classFormat.setForeground(Qt::darkMagenta);
SetRule("01_QtClasses","\\bQ[A-Za-z]+\\b",classFormat);
singleLineCommentFormat.setForeground(Qt::red);
SetRule("02_SingleLineComment","//[^\n]*",singleLineCommentFormat);
quotationFormat.setForeground(Qt::darkGreen);
SetRule("03_Quotation","\".*\"",quotationFormat);
functionFormat.setFontItalic(true);
functionFormat.setForeground(Qt::blue);
SetRule("04_Functions","\\b[A-Za-z0-9_]+(?=\\()",functionFormat);
}

HIH

Johannes