<commit_before>/*
 *  Author:
 *     <NAME> <<EMAIL>>
 *
 *  Copyright:
 *     NICTA 2013
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <QDebug>

#include "highlighter.h"


Highlighter::Highlighter(QFont& font, bool dm, QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    Rule rule;

    quoteFormat.setForeground(Qt::darkRed);
    rule.pattern = QRegExp("\"([^\"\\\\]|\\\\.)*\"");
    rule.format = quoteFormat;
    rules.append(rule);

    commentFormat.setForeground(Qt::red);
    rule.pattern = QRegExp("%[^\n]*");
    rule.format = commentFormat;
    rules.append(rule);

    QStringList patterns;
    patterns << "\\bann\\b" << "\\bannotation\\b" << "\\bany\\b"
             << "\\barray\\b" << "\\bbool\\b" << "\\bcase\\b"
             << "\\bconstraint\\b" << "\\bdefault\\b" << "\\bdiv\\b"
             << "\\bdiff\\b" << "\\belse\\b" << "\\belseif\\b"
             << "\\bendif\\b" << "\\benum\\b" << "\\bfloat\\b"
             << "\\bfunction\\b" << "\\bif\\b" << "\\binclude\\b"
             << "\\bintersect\\b" << "\\bin\\b" << "\\bint\\b"
             << "\\blet\\b" << "\\bmaximize\\b" << "\\bminimize\\b"
             << "\\bmod\\b" << "\\bnot\\b" << "\\bof\\b" << "\\boutput\\b"
             << "\\bopt\\b" << "\\bpar\\b" << "\\bpredicate\\b"
             << "\\brecord\\b" << "\\bsatisfy\\b" << "\\bset\\b"
             << "\\bsolve\\b" << "\\bstring\\b" << "\\bsubset\\b"
             << "\\bsuperset\\b" << "\\bsymdiff\\b" << "\\btest\\b"
             << "\\bthen\\b" << "\\btuple\\b" << "\\btype\\b"
             << "\\bunion\\b" << "\\bvar\\b" << "\\bvariant_record\\b"
             << "\\bwhere\\b" << "\\bxor\\b";
    QTextCharFormat format;

    format.setFontWeight(QFont::Bold);
    for (int i=0; i<patterns.size(); i++) {
        rule.pattern = QRegExp(patterns[i]);
        rule.format = format;
        rules.append(rule);
    }

    format = QTextCharFormat();
    format.setFontItalic(true);
    format.setForeground(Qt::blue);
    rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\s*\\()");
    rule.format = format;
    rules.append(rule);

    setEditorFont(font);

    commentStartExp = QRegExp("/\\*");
    commentEndExp = QRegExp("\\*/");

    setDarkMode(dm);

}

void Highlighter::setEditorFont(QFont& font)
{
    quoteFormat.setFont(font);
    commentFormat.setFont(font);
    for (int i=0; i<rules.size(); i++) {
        rules[i].format.setFont(font);
    }
}

bool fg_contains(const FixedBg& a, const FixedBg& b) {
  return (a.sl < b.sl || (a.sl == b.sl && a.sc <= b.sc))
      && (a.el > b.el || (a.el == b.el && a.ec >= b.ec));
}

void Highlighter::addFixedBg(
    unsigned int sl, unsigned int sc, unsigned int el, unsigned ec,
    QColor colour, QString tip) {

  FixedBg ifb {sl, sc, el, ec};

  for(BgMap::iterator it = fixedBg.begin();
      it != fixedBg.end();) {
    const FixedBg& fb = it.key();

    if (fg_contains(fb, ifb)) {
      it = fixedBg.erase(it);
    } else {
      ++it;
    }
  }
  fixedBg.insert(ifb, QPair<QColor, QString>(colour, tip));

}

void Highlighter::clearFixedBg() {
    fixedBg.clear();
}

void Highlighter::highlightBlock(const QString &text)
{
    QTextBlock block = currentBlock();
    for (int i=0; i<rules.size(); i++) {
        const Rule& rule = rules[i];
        QRegExp expression(rule.pattern);
        int index = expression.indexIn(text);
        while (index >= 0) {
            int length = expression.matchedLength();
            if (format(index)!=quoteFormat && format(index)!=commentFormat) {
                setFormat(index, length, rule.format);
            }
            index = expression.indexIn(text, index + length);
        }
    }

    for(QMap<FixedBg, QPair<QColor, QString> >::iterator it = fixedBg.begin();
        it != fixedBg.end(); ++it) {
      const FixedBg& fb = it.key();
      QPair<QColor, QString> val = it.value();
      QColor colour = val.first;
      QString tip = val.second;

      unsigned int blockNumber = block.blockNumber() + 1;
      if(fb.sl <= blockNumber && fb.el >= blockNumber) {
        int index = 0;
        int length = block.length();
        int endpos = index + length;

        if(fb.sl == blockNumber) {
          index = fb.sc - 1;
          if(fb.sl == fb.el) {
            length = fb.ec - index;
          }
        } else if(fb.el == blockNumber) {
          length = fb.ec;
        }

        foreach(const QTextLayout::FormatRange& fr, block.textFormats()) {
          //if(index >= fr.start && index <= fr.start + length) {
            int local_index = fr.start < index ? index : fr.start;
            int fr_endpos = fr.start + fr.length;
            int local_len = (fr_endpos < endpos ? fr_endpos : endpos) - local_index;
            QTextCharFormat fmt = fr.format;
            fmt.setBackground(colour);
            fmt.setToolTip(tip);<commit_msg>Fixed highlighing bug. (all highlighting went to end of line)<commit_after>/*
 *  Author:
 *     <NAME> <<EMAIL>>
 *
 *  Copyright:
 *     NICTA 2013
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <QDebug>

#include "highlighter.h"


Highlighter::Highlighter(QFont& font, bool dm, QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    Rule rule;

    quoteFormat.setForeground(Qt::darkRed);
    rule.pattern = QRegExp("\"([^\"\\\\]|\\\\.)*\"");
    rule.format = quoteFormat;
    rules.append(rule);

    commentFormat.setForeground(Qt::red);
    rule.pattern = QRegExp("%[^\n]*");
    rule.format = commentFormat;
    rules.append(rule);

    QStringList patterns;
    patterns << "\\bann\\b" << "\\bannotation\\b" << "\\bany\\b"
             << "\\barray\\b" << "\\bbool\\b" << "\\bcase\\b"
             << "\\bconstraint\\b" << "\\bdefault\\b" << "\\bdiv\\b"
             << "\\bdiff\\b" << "\\belse\\b" << "\\belseif\\b"
             << "\\bendif\\b" << "\\benum\\b" << "\\bfloat\\b"
             << "\\bfunction\\b" << "\\bif\\b" << "\\binclude\\b"
             << "\\bintersect\\b" << "\\bin\\b" << "\\bint\\b"
             << "\\blet\\b" << "\\bmaximize\\b" << "\\bminimize\\b"
             << "\\bmod\\b" << "\\bnot\\b" << "\\bof\\b" << "\\boutput\\b"
             << "\\bopt\\b" << "\\bpar\\b" << "\\bpredicate\\b"
             << "\\brecord\\b" << "\\bsatisfy\\b" << "\\bset\\b"
             << "\\bsolve\\b" << "\\bstring\\b" << "\\bsubset\\b"
             << "\\bsuperset\\b" << "\\bsymdiff\\b" << "\\btest\\b"
             << "\\bthen\\b" << "\\btuple\\b" << "\\btype\\b"
             << "\\bunion\\b" << "\\bvar\\b" << "\\bvariant_record\\b"
             << "\\bwhere\\b" << "\\bxor\\b";
    QTextCharFormat format;

    format.setFontWeight(QFont::Bold);
    for (int i=0; i<patterns.size(); i++) {
        rule.pattern = QRegExp(patterns[i]);
        rule.format = format;
        rules.append(rule);
    }

    format = QTextCharFormat();
    format.setFontItalic(true);
    format.setForeground(Qt::blue);
    rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\s*\\()");
    rule.format = format;
    rules.append(rule);

    setEditorFont(font);

    commentStartExp = QRegExp("/\\*");
    commentEndExp = QRegExp("\\*/");

    setDarkMode(dm);

}

void Highlighter::setEditorFont(QFont& font)
{
    quoteFormat.setFont(font);
    commentFormat.setFont(font);
    for (int i=0; i<rules.size(); i++) {
        rules[i].format.setFont(font);
    }
}

bool fg_contains(const FixedBg& a, const FixedBg& b) {
  return (a.sl < b.sl || (a.sl == b.sl && a.sc <= b.sc))
      && (a.el > b.el || (a.el == b.el && a.ec >= b.ec));
}

void Highlighter::addFixedBg(
    unsigned int sl, unsigned int sc, unsigned int el, unsigned ec,
    QColor colour, QString tip) {

  FixedBg ifb {sl, sc, el, ec};

  for(BgMap::iterator it = fixedBg.begin();
      it != fixedBg.end();) {
    const FixedBg& fb = it.key();

    if (fg_contains(fb, ifb)) {
      it = fixedBg.erase(it);
    } else {
      ++it;
    }
  }
  fixedBg.insert(ifb, QPair<QColor, QString>(colour, tip));

}

void Highlighter::clearFixedBg() {
    fixedBg.clear();
}

void Highlighter::highlightBlock(const QString &text)
{
    QTextBlock block = currentBlock();
    for (int i=0; i<rules.size(); i++) {
        const Rule& rule = rules[i];
        QRegExp expression(rule.pattern);
        int index = expression.indexIn(text);
        while (index >= 0) {
            int length = expression.matchedLength();
            if (format(index)!=quoteFormat && format(index)!=commentFormat) {
                setFormat(index, length, rule.format);
            }
            index = expression.indexIn(text, index + length);
        }
    }

    for(QMap<FixedBg, QPair<QColor, QString> >::iterator it = fixedBg.begin();
        it != fixedBg.end(); ++it) {
      const FixedBg& fb = it.key();
      QPair<QColor, QString> val = it.value();
      QColor colour = val.first;
      QString tip = val.second;

      unsigned int blockNumber = block.blockNumber() + 1;
      if(fb.sl <= blockNumber && fb.el >= blockNumber) {
        int index = 0;
        int length = block.length();

        if(fb.sl == blockNumber) {
          index = fb.sc - 1;
          if(fb.sl == fb.el) {
            length = fb.ec - index;
          }
        } else if(fb.el == blockNumber) {
          length = fb.ec;
        }

        int endpos = index + length;
        foreach(const QTextLayout::FormatRange& fr, block.textFormats()) {
          //if(index >= fr.start && index <= fr.start + length) {
            int local_index = fr.start < index ? index : fr.start;
            int fr_endpos = fr.start + fr.length;
            int local_len = (fr_endpos < endpos ? fr_endpos : endpos) - local_index;
            QTextCharFormat fmt = fr.format;
            fmt.setBackground(colour);
            fmt.setToolTip(tip);
{'fraction_non_alphanumeric': 0.2028913260219342, 'fraction_numerical': 0.003389830508474576, 'mean_word_length': 2.0517188926072407, 'pattern_counts': {'":': 0, '<': 229, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1046303', 'n_tokens_mistral': 3625, 'n_tokens_neox': 3406, 'n_words': 702}