void SmkMarkHighlighter::highlightBlock(const QString& text) { // highlight with regrxp for(int i=0; i<format_.size(); i++) { int index = regexp_[i].indexIn(text); while(index >= 0) { int length = regexp_[i].matchedLength(); this->setFormat(index, length, format_[i]); index = regexp_[i].indexIn(text, index + length); } } // code block and latex block highlight if(currentBlockState() == -1) setCurrentBlockState(0); QTextCharFormat codeFormat; codeFormat.setForeground(QColor(qSmkApp()->option("color.code"))); _aux_multiBlockMatch(text, "`", "`", codeFormat, 0x0001); // _aux_multiBlockMatch(text, "``", "``", codeFormat, 0x0002); // _aux_multiBlockMatch(text, "```", "```", codeFormat, 0x004); QTextCharFormat latexFormat; latexFormat.setForeground(QColor(qSmkApp()->option("color.latex"))); _aux_multiBlockMatch(text, "${", "}$", latexFormat, 0x1000); _aux_multiBlockMatch(text, "$$", "$$", latexFormat, 0x2000); }
// Clears the requested state for the current text block void XHTMLHighlighter::ClearState(int state) { int current_state = currentBlockState(); // Remove the current state from the list current_state = current_state & ~state; setCurrentBlockState(current_state); }
// Sets the requested state for the current text block void XHTMLHighlighter::SetState(int state) { int current_state = currentBlockState(); // Add the current state to the list current_state = current_state | state; setCurrentBlockState(current_state); }
bool Highlighter::matchMultiline(const QString& text, const ::HighlightingRule& rule) { QRegExp delimiter(rule.pattern); int start = 0; int add = 0; int end = 0; int length = 0; if (previousBlockState() != rule.index) { start = delimiter.indexIn(text); add = delimiter.matchedLength(); } while (start >= 0) { end = delimiter.indexIn(text, start + add); if (end >= add) { length = end - start + add + delimiter.matchedLength(); setCurrentBlockState(0); } else { setCurrentBlockState(rule.index); length = text.length() - start + add; } QTextCharFormat fmt; if (m_Formats.contains(rule.t)) fmt = m_Formats[rule.t]; setFormat(start, length, fmt); start = delimiter.indexIn(text, start + length); } return currentBlockState() == rule.index; }
/** handle nested comments and simple minded attributes */ void lqGvSynCol::highlightBlock(const QString &text) { QString begComm("/\\*"); QString number("\\d+(?:\\.\\d+)?"); QString symbol("\\w+"); QString quoted("\"[^\"]*\""); QString edges("--|->"); QRegExp tokens(QString("(%1)|(%2)|(%3)|(%4)|(%5)|#").arg(begComm, number, symbol, quoted, edges)); QRegExp endComm("\\*/"); // simple state machine if (currentBlock().blockNumber() > 0) setCurrentBlockState(previousBlockState()); else setCurrentBlockState(0); for (int i = 0, j, l; ; i = j + l) if (currentBlockState()) { // in multiline comment if ((j = endComm.indexIn(text, i)) == -1) { setFormat(i, text.length() - i, fmt[Comm]); break; } setFormat(i, j - i + (l = 2), fmt[Comm]); setCurrentBlockState(0); } else { if ((j = tokens.indexIn(text, i)) == -1) break; QStringList ml = tokens.capturedTexts(); Q_ASSERT(ml.length() == 5+1); if ((l = ml[1].length())) { // begin multiline comment setFormat(j, l, fmt[Comm]); setCurrentBlockState(1); } else if ((l = ml[2].length())) { // number setFormat(j, l, fmt[Number]); } else if ((l = ml[3].length())) { // symbol if (keyws.contains(ml[3])) setFormat(j, l, fmt[Keyw]); else if (attrs.contains(ml[3])) setFormat(j, l, fmt[Attr]); else setFormat(j, l, fmt[Unknown]); } else if ((l = ml[4].length())) { // quoted setFormat(j, l, fmt[Quoted]); } else if ((l = ml[5].length())) { // edge setFormat(j, l, fmt[Edge]); } else { // single line comment setFormat(j, text.length() - i, fmt[Comm]); break; } } // rather useless - anyway textChanged will fire after completion if (currentBlock().blockNumber() == document()->blockCount() - 1) emit completed(); }
// Checks if the requested state is set // for the current text block bool XHTMLHighlighter::StateChecked(int state) const { int current_state = currentBlockState(); // Check if our state is in the list if ((current_state & state) != 0) { return true; } else { return false; } }
void SmkMarkHighlighter::_aux_multiBlockMatch( const QString& text, const QString& bgnFlag, const QString& endFlag, const QTextCharFormat& format, const unsigned field ) { if(previousBlockState() == -1) return; setCurrentBlockState(currentBlockState() & (~field)); if(previousBlockState() & field) { int endid = text.indexOf(endFlag, 0); if(endid != -1) { // we find a endFlag setFormat(0, endid+endFlag.length(), format); } else { // we do not find a endFlag, mark this line and go on setFormat(0, text.length(), format); // if(previousBlockState() != -1) setCurrentBlockState(currentBlockState() | field); } } else { int bgnid = text.indexOf(bgnFlag, 0); while(bgnid != -1) { int endid = text.indexOf(endFlag, bgnid+bgnFlag.length()); if(endid != -1) { // we find a endFlag setFormat(bgnid, endid+endFlag.length()-bgnid, format); bgnid = text.indexOf(bgnFlag, endid+endFlag.length()); } else { // we do not find a endFlag, mark this line and go on setFormat(bgnid, text.length()-bgnid, format); setCurrentBlockState(currentBlockState() | field); break; } }//while(... }//if..else... }
/** handle nested comments and simple minded Prolog syntax */ void plMiniSyntax::highlightBlock(const QString &text) { // simple state machine int nb = currentBlock().blockNumber(); if (nb > 0) { setCurrentBlockState(previousBlockState()); if (nb % 10 == 0) do_events(); } else { startToEnd.start(); qDebug() << "starting at " << QTime::currentTime(); setCurrentBlockState(0); } for (int i = 0, j, l; ; i = j + l) if (currentBlockState()) { // in multiline comment if ((j = text.indexOf("*/", i)) == -1) { setFormat(i, text.length() - i, fmt[Comment]); break; } setFormat(i, j - i + (l = 2), fmt[Comment]); setCurrentBlockState(0); } else { if ((j = text.indexOf("/*", i)) >= 0) { // begin multiline comment setFormat(j, l = 2, fmt[Comment]); setCurrentBlockState(1); } else { if ((j = tokens.indexIn(text, i)) == -1) break; QStringList ml = tokens.capturedTexts(); Q_ASSERT(ml.length() == 5+1); if ((l = ml[1].length())) { // number setFormat(j, l, fmt[Number]); } else if ((l = ml[2].length())) { // symbol setFormat(j, l, fmt[Atom]); } else if ((l = ml[3].length())) { // var setFormat(j, l, fmt[Variable]); } else if ((l = ml[4].length())) { // quoted setFormat(j, l, fmt[String]); } else if ((l = ml[5].length())) { // operator setFormat(j, l, fmt[Operator]); } else { // single line comment setFormat(j, text.length() - i, fmt[Comment]); break; } } } if (currentBlock() == document()->lastBlock()) qDebug() << "done at " << QTime::currentTime() << "in" << startToEnd.elapsed(); }
bool BashHighlighter::matchMultiline(const QString& text, const QRegExp& delimiter, const int inState, const QTextCharFormat& style) { int start = -1; int add = -1; int end = -1; int length = 0; // If inside triple-single quotes, start at 0 if ( previousBlockState() == inState ) { start = 0; add = 0; } // Otherwise, look for the delimiter on this line else { start = delimiter.indexIn(text); // Move past this match add = delimiter.matchedLength(); } // As long as there's a delimiter match on this line... while ( start >= 0 ) { // Look for the ending delimiter end = delimiter.indexIn(text, start + add); // Ending delimiter on this line? if ( end >= add ) { length = end - start + add + delimiter.matchedLength(); setCurrentBlockState(0); } // No; multi-line string else { setCurrentBlockState(inState); length = text.length() - start + add; } // Apply formatting and look for next setFormat(start, length, style); start = delimiter.indexIn(text, start + length); } // Return True if still inside a multi-line string, False otherwise if ( currentBlockState() == inState ) return true; else return false; }
void ScriptEditorSyntaxHighlighter::highlightBlock(const QString & szText) { if(szText.isEmpty()) { setCurrentBlockState(previousBlockState()); return; } int iIndexStart=0; setCurrentBlockState(0); if(previousBlockState() == 1) { // inside a multiline comment int iCommentEnd = szText.indexOf("*/"); if(iCommentEnd < 0) { // not found: comment until the end of the block setCurrentBlockState(1); setFormat(iIndexStart,szText.length(),commentFormat); return; } // skip 2 chars iCommentEnd+=2; // end of comment found setFormat(iIndexStart,iCommentEnd - iIndexStart,commentFormat); iIndexStart = iCommentEnd; } SKIP_SPACES if (iIndexStart == szText.size()) return; // check 'commands' and comments int iCommandStart=iIndexStart; if (szText.at(iIndexStart).unicode()!='$' && szText.at(iIndexStart).unicode()!='{' && szText.at(iIndexStart).unicode()!='}' && szText.at(iIndexStart).unicode()!='%') { switch(szText.at(iIndexStart).unicode()) { case '#': // single line comment, bash style while(iIndexStart<szText.size() && szText.at(iIndexStart).unicode() != '\n') iIndexStart++; setFormat(iCommandStart,iIndexStart-iCommandStart,commentFormat); break; case '/': if((iIndexStart+1)<szText.size()) { if(szText.at(iIndexStart+1).unicode()=='/') { // single line comment, c++ style iIndexStart++; while(iIndexStart<szText.size() && szText.at(iIndexStart).unicode() != '\n') iIndexStart++; setFormat(iCommandStart,iIndexStart-iCommandStart,commentFormat); break; } if(szText.at(iIndexStart+1).unicode()=='*') { // multi line comment, c style iIndexStart++; setCurrentBlockState(1); while(iIndexStart<szText.size()) { if((iIndexStart+1)<szText.size()) { if(szText.at(iIndexStart).unicode() == '*' && szText.at(iIndexStart+1).unicode() == '/') { iIndexStart+=2; setCurrentBlockState(0); break; } } iIndexStart++; } setFormat(iCommandStart,iIndexStart-iCommandStart,commentFormat); SKIP_SPACES if(currentBlockState()==0) { iCommandStart=iIndexStart; } else { break; } // else fallback to command (a command can start at the end of a /* comment */) } // else not a comment, fallback to command } default: //command while(iIndexStart<szText.size() && (szText.at(iIndexStart).isLetterOrNumber() || (szText.at(iIndexStart).unicode() == '.') || (szText.at(iIndexStart).unicode() == '_') || (szText.at(iIndexStart).unicode()== ':') )) { iIndexStart++; } setFormat(iCommandStart,iIndexStart-iCommandStart,keywordFormat); break; } }
void SyntaxHighlighter::highlightBlock(const QString& text) { if (currentBlockState() > 0) setFormat(0, text.length(), d.color); }
void TMSyntax::highlightBlock(const QString &text) { if(previousBlockState()==SYN_ERROR){ setCurrentBlockState(1); setFormat(0,text.size(),io_format::syntax_error); return; } if(currentBlockState()==2){ //setCurrentBlockState(1); setFormat(0,text.size(),io_format::semantic_error); return; } setCurrentBlockState(-1); switch(io_ex::line_type(text)){ case io_ex::LINE_OPTION: setFormat(0,text.size(),io_format::option); break; case io_ex::LINE_VALID_MACHINE: case io_ex::LINE_VALID_STATE: break_line_token(text); switch(token_list[0].type){ case io_ex::TOKEN_STATE_SPEC: setFormat(token_list[0].start, token_list[0].count, io_format::state_spec); break; case io_ex::TOKEN_STATE: setFormat(token_list[0].start,token_list[0].count,io_format::state); break; case io_ex::TOKEN_MACHINE: setFormat(token_list[0].start,token_list[0].count,io_format::machine); break; default: break; } switch(token_list[1].type){ case io_ex::TOKEN_CHARACTER_SPEC: setFormat(token_list[1].start,token_list[1].count,io_format::character_spec); break; case io_ex::TOKEN_CHARACTER: setFormat(token_list[1].start,token_list[1].count,io_format::character_spec); break; default: break; } switch (token_list[2].type) { case io_ex::TOKEN_STATE_SPEC: setFormat(token_list[2].start,token_list[2].count,io_format::state_spec); break; case io_ex::TOKEN_STATE: setFormat(token_list[2].start,token_list[2].count,io_format::state); break; case io_ex::TOKEN_MACHINE: setFormat(token_list[2].start,token_list[2].count,io_format::machine); break; default: break; } switch (token_list[3].type) { case io_ex::TOKEN_COMMAND: setFormat(token_list[3].start,token_list[3].count,io_format::command); break; case io_ex::TOKEN_CHARACTER_SPEC: setFormat(token_list[3].start,token_list[3].count,io_format::character_spec); break; case io_ex::TOKEN_CHARACTER: setFormat(token_list[3].start,token_list[3].count,io_format::character); break; default: break; } break; case io_ex::LINE_COMMENT: setFormat(0,text.size(),io_format::comment); break; case io_ex::LINE_WHITE: setFormat(0,text.size(),io_format::blank); break; case io_ex::LINE_ERROR: default: setFormat(0,text.size(),io_format::syntax_error); setCurrentBlockState(1); break; } }
// Check if the current block is inside a "here document" and format it accordingly. bool Highlighter::isHereDocument (const QString &text) { QTextCharFormat blockFormat; blockFormat.setForeground (QColor (126, 0, 230)); QTextCharFormat delimFormat = blockFormat; delimFormat.setFontWeight (QFont::Bold); QString delimStr; /* Kate uses something like "<<(?:\\s*)([\\\\]{,1}[^\\s]+)" */ QRegExp delim = QRegExp ("<<(?:\\s*)([\\\\]{,1}[A-Za-z0-9_]+)|<<(?:\\s*)(\'[A-Za-z0-9_]+\')|<<(?:\\s*)(\"[A-Za-z0-9_]+\")"); int pos, i; /* format the start delimiter */ if (previousBlockState() != delimState - 1 && currentBlockState() != delimState - 1 && (pos = delim.indexIn (text)) >= 0) { i = 1; while ((delimStr = delim.cap (i)).isEmpty() && i <= 3) { ++i; delimStr = delim.cap (i); } /* remove quotes */ if (delimStr.contains ('\'')) delimStr = delimStr.split ('\'').at (1); if (delimStr.contains ('\"')) delimStr = delimStr.split ('\"').at (1); /* remove the start backslash if it exists */ if (QString (delimStr.at (0)) == "\\") delimStr = delimStr.remove (0, 1); if (!delimStr.isEmpty()) { setCurrentBlockState (delimState); setFormat (text.indexOf (delimStr, pos), delimStr.length(), delimFormat); TextBlockData *data = static_cast<TextBlockData *>(currentBlock().userData()); data->insertInfo (delimStr); data->insertInfo (true); setCurrentBlockUserData (data); return false; } } if (previousBlockState() == delimState - 1 || previousBlockState() == delimState) { QTextBlock block = currentBlock().previous(); TextBlockData *data = static_cast<TextBlockData *>(block.userData()); delimStr = data->delimiter(); if (text == delimStr || (text.startsWith (delimStr) && text.indexOf (QRegExp ("\\s+")) == delimStr.length())) { /* format the end delimiter */ setFormat (0, delimStr.length(), delimFormat); /* we need this in docChanged() */ data = static_cast<TextBlockData *>(currentBlock().userData()); data->insertInfo (true); setCurrentBlockUserData (data); return false; } else { /* format the contents */ TextBlockData *data = static_cast<TextBlockData *>(currentBlock().userData()); data->insertInfo (delimStr); setCurrentBlockUserData (data); setCurrentBlockState (delimState - 1); setFormat (0, text.length(), blockFormat); return true; } } return false; }