Guest User

Untitled

a guest
Jul 11th, 2014
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.13 KB | None | 0 0
  1. #include "PythonSyntaxHighlighter.h"
  2.  
  3. PythonSyntaxHighlighter::PythonSyntaxHighlighter(QTextDocument *parent)
  4.  : QSyntaxHighlighter(parent)
  5. {
  6.  keywords = QStringList() << "and" << "assert" << "break" << "class" << "continue" << "def" <<
  7.         "del" << "elif" << "else" << "except" << "exec" << "finally" <<
  8.         "for" << "from" << "global" << "if" << "import" << "in" <<
  9.         "is" << "lambda" << "not" << "or" << "pass" << "print" <<
  10.         "raise" << "return" << "try" << "while" << "yield" <<
  11.         "None" << "True" << "False";
  12.  
  13.  operators = QStringList() << "=" <<
  14.         // Comparison
  15.         "==" << "!=" << "<" << "<=" << ">" << ">=" <<
  16.         // Arithmetic
  17.         "\\+" << "-" << "\\*" << "/" << "//" << "%" << "\\*\\*" <<
  18.         // In-place
  19.         "\\+=" << "-=" << "\\*=" << "/=" << "%=" <<
  20.         // Bitwise
  21.         "\\^" << "\\|" << "&" << "~" << ">>" << "<<";
  22.  
  23.  braces = QStringList() << "{" << "}" << "\\(" << "\\)" << "\\[" << "]";
  24.  
  25.  basicStyles.insert("keyword", getTextCharFormat("blue"));
  26.  basicStyles.insert("operator", getTextCharFormat("red"));
  27.  basicStyles.insert("brace", getTextCharFormat("darkGray"));
  28.     basicStyles.insert("defclass", getTextCharFormat("black", "bold"));
  29.  basicStyles.insert("brace", getTextCharFormat("darkGray"));
  30.  basicStyles.insert("string", getTextCharFormat("magenta"));
  31.  basicStyles.insert("string2", getTextCharFormat("darkMagenta"));
  32.  basicStyles.insert("comment", getTextCharFormat("darkGreen", "italic"));
  33.  basicStyles.insert("self", getTextCharFormat("black", "italic"));
  34.  basicStyles.insert("numbers", getTextCharFormat("brown"));
  35.  
  36.  triSingleQuote.setPattern("'''");
  37.  triDoubleQuote.setPattern("\"\"\"");
  38.  
  39.  initializeRules();
  40. }
  41.  
  42. void PythonSyntaxHighlighter::initializeRules()
  43. {
  44.  foreach (QString currKeyword, keywords)
  45.  {
  46.   rules.append(HighlightingRule(QString("\\b%1\\b").arg(currKeyword), 0, basicStyles.value("keyword")));
  47.  }
  48.  foreach (QString currOperator, operators)
  49.  {
  50.   rules.append(HighlightingRule(QString("%1").arg(currOperator), 0, basicStyles.value("operator")));
  51.  }
  52.  foreach (QString currBrace, braces)
  53.  {
  54.   rules.append(HighlightingRule(QString("%1").arg(currBrace), 0, basicStyles.value("brace")));
  55.  }
  56.  // 'self'
  57.     rules.append(HighlightingRule("\\bself\\b", 0, basicStyles.value("self")));
  58.  
  59.     // Double-quoted string, possibly containing escape sequences
  60.  // FF: originally in python : r'"[^"\\]*(\\.[^"\\]*)*"'
  61.     rules.append(HighlightingRule("\"[^\"\\\\]*(\\\\.[^\"\\\\]*)*\"", 0, basicStyles.value("string")));
  62.     // Single-quoted string, possibly containing escape sequences
  63.  // FF: originally in python : r"'[^'\\]*(\\.[^'\\]*)*'"
  64.  rules.append(HighlightingRule("'[^'\\\\]*(\\\\.[^'\\\\]*)*'", 0, basicStyles.value("string")));
  65.  
  66.     // 'def' followed by an identifier
  67.  // FF: originally: r'\bdef\b\s*(\w+)'
  68.     rules.append(HighlightingRule("\\bdef\\b\\s*(\\w+)", 1, basicStyles.value("defclass")));
  69.     //  'class' followed by an identifier
  70.  // FF: originally: r'\bclass\b\s*(\w+)'
  71.  rules.append(HighlightingRule("\\bclass\\b\\s*(\\w+)", 1, basicStyles.value("defclass")));
  72.  
  73.     // From '#' until a newline
  74.  // FF: originally: r'#[^\\n]*'
  75.     rules.append(HighlightingRule("#[^\\n]*", 0, basicStyles.value("comment")));
  76.  
  77.     // Numeric literals
  78.     rules.append(HighlightingRule("\\b[+-]?[0-9]+[lL]?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?[0-9]+[lL]?\b'
  79.     rules.append(HighlightingRule("\\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b'
  80.     rules.append(HighlightingRule("\\b[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b'
  81. }
  82.  
  83. void PythonSyntaxHighlighter::highlightBlock(const QString &text)
  84. {
  85.  foreach (HighlightingRule currRule, rules)
  86.  {
  87.   int idx = currRule.pattern.indexIn(text, 0);
  88.   while (idx >= 0)
  89.   {
  90.    // Get index of Nth match
  91.    idx = currRule.pattern.pos(currRule.nth);
  92.    int length = currRule.pattern.cap(currRule.nth).length();
  93.    setFormat(idx, length, currRule.format);
  94.    idx = currRule.pattern.indexIn(text, idx + length);
  95.   }
  96.  }
  97.  
  98.  setCurrentBlockState(0);
  99.  
  100.     // Do multi-line strings
  101.     bool isInMultilne = matchMultiline(text, triSingleQuote, 1, basicStyles.value("string2"));
  102.     if (!isInMultilne)
  103.   isInMultilne = matchMultiline(text, triDoubleQuote, 2, basicStyles.value("string2"));
  104. }
  105.  
  106. bool PythonSyntaxHighlighter::matchMultiline(const QString &text, const QRegExp &delimiter, const int inState, const QTextCharFormat &style)
  107. {
  108.     int start = -1;
  109.  int add = -1;
  110.  int end = -1;
  111.  int length = 0;
  112.  
  113.  // If inside triple-single quotes, start at 0
  114.  if (previousBlockState() == inState) {
  115.         start = 0;
  116.         add = 0;
  117.  }
  118.  // Otherwise, look for the delimiter on this line
  119.  else {
  120.         start = delimiter.indexIn(text);
  121.         // Move past this match
  122.         add = delimiter.matchedLength();
  123.  }
  124.  
  125.     // As long as there's a delimiter match on this line...
  126.     while (start >= 0) {
  127.         // Look for the ending delimiter
  128.         end = delimiter.indexIn(text, start + add);
  129.         // Ending delimiter on this line?
  130.         if (end >= add) {
  131.             length = end - start + add + delimiter.matchedLength();
  132.             setCurrentBlockState(0);
  133.   }
  134.         // No; multi-line string
  135.         else {
  136.             setCurrentBlockState(inState);
  137.             length = text.length() - start + add;
  138.   }
  139.         // Apply formatting and look for next
  140.         setFormat(start, length, style);
  141.         start = delimiter.indexIn(text, start + length);
  142.  }
  143.     // Return True if still inside a multi-line string, False otherwise
  144.     if (currentBlockState() == inState)
  145.         return true;
  146.     else
  147.         return false;
  148. }
  149.  
  150. const QTextCharFormat PythonSyntaxHighlighter::getTextCharFormat(const QString &colorName, const QString &style)
  151. {
  152.  QTextCharFormat charFormat;
  153.  QColor color(colorName);
  154.  charFormat.setForeground(color);
  155.  if (style.contains("bold", Qt::CaseInsensitive))
  156.   charFormat.setFontWeight(QFont::Bold);
  157.  if (style.contains("italic", Qt::CaseInsensitive))
  158.   charFormat.setFontItalic(true);
  159.  return charFormat;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment