Пример #1
0
// Handle the general case
QString GumboInterface::fix_self_closing_tags(const QString &source)
{
    QString newsource = source;
    QRegularExpression selfclosed("<\\s*([a-zA-Z]+)(\\s*[^>/]*)/\\s*>");
    QRegularExpressionMatch match = selfclosed.match(newsource, 0);
    while (match.hasMatch()) {
        if (match.capturedStart() == -1) {
            break;
        }
        QString tag = match.captured(0);
        int sp = match.capturedStart(0);
        int n = match.capturedLength(0);
        QString name = match.captured(1);
        QString atts = match.captured(2);;
        atts = atts.trimmed();
        if (!atts.isEmpty()) {
            atts = " " + atts;
        }
        int nsp = sp + n;
        if (!allowed_void_tags.contains(name)) {
            QString newtag = "<" + name + atts + "></" + name + ">";
            newsource = newsource.replace(sp,n,newtag);
            nsp = sp + newtag.length();
        }
        match = selfclosed.match(newsource, nsp);
    }
    return newsource;
}
// The actual generation engine
QString ShopTemplateManager::Generate(const Items &items) {
    QString temp = shopTemplate;
    {
        QRegularExpression expr("{(?<key>.+?)(?<options>(\\|(.+?))*?)}");
        QRegularExpressionMatchIterator matcher = expr.globalMatch(shopTemplate);
        int offset = 0;
        while (matcher.hasNext()) {
            QRegularExpressionMatch match = matcher.next();
            QString key = match.captured("key").toLower();
            int startPos = offset + match.capturedStart();
            int len = match.capturedLength();

            QStringList optionsAndData = match.captured("options").split("|", QString::SkipEmptyParts);
            QHash<QString, QString> options;
            for (QString optionAndData : optionsAndData) {
                int split = optionAndData.indexOf(":");
                if (split == -1) {
                    options.insert(optionAndData.toLower(), "");
                }
                else {
                    QString option = optionAndData.left(split).toLower();
                    QString data = optionAndData.mid(split + 1);
                    options.insert(option, data);
                }
            }

            QString replacement = FetchFromKey(key, items, &options);

            temp.replace(startPos, len, replacement);
            offset += replacement.length() - len;
        }
    }

    // Now clean up empty spoiler tags!
    int matches = -1;
    while (matches != 0){
        QRegularExpression expr("\\[spoiler=\\\"(?>.*?\\\"\\])(?>\\s*?\\[\\/spoiler\\]\\n)");
        QRegularExpressionMatchIterator matcher = expr.globalMatch(temp);
        int offset = 0;
        matches = 0;
        while (matcher.hasNext()) {
            QRegularExpressionMatch match = matcher.next();
            int startPos = match.capturedStart() + offset;
            int length = match.capturedLength();

            temp.remove(startPos, length);
            offset -= length;
            matches++;
        }
    }

    return temp;
}
Пример #3
0
QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
                                                          const QString &entry)
{
    QList<LocatorFilterEntry> goodEntries;
    QList<LocatorFilterEntry> betterEntries;
    const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);

    const QRegularExpression regexp = createRegExp(fp.filePath);
    if (!regexp.isValid())
        return goodEntries;

    const QList<Entry> editorEntries = editors();
    for (const Entry &editorEntry : editorEntries) {
        if (future.isCanceled())
            break;
        QString fileName = editorEntry.fileName.toString();
        if (fileName.isEmpty())
            continue;
        QString displayName = editorEntry.displayName;
        const QRegularExpressionMatch match = regexp.match(displayName);
        if (match.hasMatch()) {
            LocatorFilterEntry filterEntry(this, displayName, QString(fileName + fp.postfix));
            filterEntry.extraInfo = FileUtils::shortNativePath(FileName::fromString(fileName));
            filterEntry.fileName = fileName;
            filterEntry.highlightInfo = highlightInfo(match);
            if (match.capturedStart() == 0)
                betterEntries.append(filterEntry);
            else
                goodEntries.append(filterEntry);
        }
    }
    betterEntries.append(goodEntries);
    return betterEntries;
}
Пример #4
0
/**
 * @brief prepend symbol on nth match
 * @param input input string
 * @param number_length the length of the number, will prepend symbol
 * if the length smaller than this number
 * @param nth the number of match
 * @param reg the pattern want to find
 * @param symbol symbol prepand before the number
 * @return the input after symbol prepend if match the condition; if the reg
 * found the match pattern but the target length less than number_length, do nothing;
 * if reg do not find any match, return "the number of match is out of range
 * or found no match in this string"
 */
QString prepend_symbol_on_nth_match(QString const &input, int number_length,
                                    int nth, const QRegularExpression &reg, QChar symbol)
{
    auto it = reg.globalMatch(input);
    QRegularExpressionMatch match;
    int count = 0;

    while (it.hasNext()){
        match = it.next();
        if(count == nth){
            if(match.hasMatch()){
                QString new_file_name = input;
                if(!match.captured(1).isEmpty()){
                    if(match.capturedLength(0) < number_length){
                        new_file_name.insert(match.capturedStart(0),
                                             QString(number_length - match.capturedLength(0),
                                                     symbol));
                    }
                }
                return new_file_name;
            }else{
                break;
            }
        }
        ++count;
    }

    return "the number of match is out of range or found no match in this string";
}
Пример #5
0
bool QuickFindPattern::isLineMatchingBackward(
        const QString& line, int column ) const
{
    int pos = 0;

    if ( ! active_ )
        return false;

    QRegularExpressionMatchIterator matches = regexp_.globalMatch(line);
    QRegularExpressionMatch lastMatch;
    while ( matches.hasNext() ) {
        QRegularExpressionMatch nextMatch = matches.peekNext();
        if ( column >= 0 && nextMatch.capturedEnd() >= column ) {
            break;
        }

        lastMatch = matches.next();
    }

    if ( lastMatch.hasMatch() ) {
        lastMatchStart_ = lastMatch.capturedStart();
        lastMatchEnd_ = lastMatch.capturedEnd() - 1;
        return true;
    }
    else {
        return false;
    }
}
Пример #6
0
void HtmlParser::parse()
{
    while(!_downloaded)
    {
        QThread::msleep(10);
    }
    _info->_status = UrlInfo::PARSING;
    emit processing(_info.data());
    _info->_found = _content.contains(_text, Qt::CaseInsensitive);


    int start_offset = -1;
    QRegularExpression regExp("(?:https?|ftp)://(((((((((\\w|\\d)|\\055)|\\056)|\\046)|\\077)|\\043)|\\045)|\\057)|\\075)+");

    while (true)
    {
        QRegularExpressionMatch match = regExp.match(_content, ++start_offset);
        if (!match.hasMatch())
            break;
        start_offset = match.capturedStart();
        int end_offset = match.capturedEnd();
        _links << new HtmlParser(_content.mid(start_offset, end_offset), _text);
    }
    _content.clear();
    if (_downloader)
        delete _downloader;
    _downloader = nullptr;
    _info->_status = UrlInfo::FINISHED;
    emit processing(_info.data());
}
Пример #7
0
void Highlighter::highlightBlock(const QString &text)
{
	foreach (const HighlightingRule &rule, highlightingRules)
	{
		QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
		while (matchIterator.hasNext())
		{
			QRegularExpressionMatch match = matchIterator.next();
			setFormat(match.capturedStart(), match.capturedLength(), rule.format);
		}
	}
Пример #8
0
void SyntaxHighlighter::highlightBlock(const QString &text) {
  for (std::size_t i = 0; i < _keywords.size(); i++) {
    const KeywordRule &rule = _keywords.at(i);
    QRegularExpressionMatchIterator it = rule.rulePattern.globalMatch(text);
    while (it.hasNext()) {
      QRegularExpressionMatch match = it.next();
      setFormat(
          match.capturedStart(), match.capturedLength(), rule.ruleTextFormat);
    }
  }
}
Пример #9
0
void Template::translate(ITemplateTranslationProvider &provider)
{
	//This regex captures expressions of the form
	//<?= tr("This is a test") ?> and <?= tr("optional %1 parameters %2","bla","blu") ?>
	//The first capture group is the key (untranslated string), the second the optional list of parameters
	const QRegularExpression regexp = QRegularExpression("<\\?=\\s*tr\\(\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"((?:,\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")*)\\s*\\)\\?>");
	//This one is used to extract the parameters using global matching
	const QRegularExpression paramExp = QRegularExpression(",\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"");

	int offset = 0;
	QRegularExpressionMatch match;
	do
	{
		match = regexp.match(*this,offset);

		if(match.hasMatch())
		{
			int start = match.capturedStart(0);
			int len = match.capturedLength(0);
			QString key = match.captured(1);

			//replace escaped double and single quotes
			key.replace("\\\"","\"");
			key.replace("\\'", "'");

			QString translation = provider.getTranslation(key);

			//find out if we have optional parameters
			if(match.capturedLength(2)>0)
			{
				QString params = match.captured(2);
				//extract each optional parameter
				QRegularExpressionMatchIterator it = paramExp.globalMatch(params);
				while(it.hasNext())
				{
					QRegularExpressionMatch paramMatch = it.next();
					QString param = paramMatch.captured(1);

					//replace escaped quotes
					param.replace("\\\"","\"");
					param.replace("\\'", "'");

					//apply the param
					translation = translation.arg(param);
				}
			}

			this->replace(start,len,translation);
			offset = start+translation.length();
		}
	}while(match.hasMatch());
}
Пример #10
0
QString StringUtils::htmlEncode(
    QString text, bool urlAsLinks, bool newlineAsBr) {
  QString s;
  QHash<int,int> linksIndexes; // start of link index -> length of link
  if (urlAsLinks) {
    QRegularExpressionMatchIterator it = linkRe.globalMatch(text);
    while (it.hasNext()) {
      QRegularExpressionMatch match = it.next();
      linksIndexes.insert(match.capturedStart(0), match.capturedLength(0));
    }
  }
  for (int i = 0; i < text.length(); ) {
    if (urlAsLinks && linksIndexes.contains(i)) {
      int l = linksIndexes.value(i);
      QString html = htmlEncode(text.mid(i, l), false), href = html;
      href.replace("\"", "%22");
      s.append("<a href=\"").append(href).append("\">").append(html)
          .append("</a>");
      i += l;
    } else {
      const QChar c = text.at(i);
      switch(c.toLatin1()) {
      case '<':
        s.append("&lt;");
        break;
      case '>':
        s.append("&gt;");
        break;
      case '&':
        s.append("&amp;");
        break;
      case '"':
        s.append("&#34;");
        break;
      case '\'':
        s.append("&#39;");
        break;
      case '\n':
        if (newlineAsBr)
          s.append("<br/>\n");
        else
          s.append(c);
        break;
      default:
        s.append(c);
      }
      ++i;
    }
  }
  return s;
}
Пример #11
0
    foreach (OnePartRule rule, onepartrules)
    {
        QRegularExpressionMatchIterator i = rule.pattern.globalMatch(text);

        while (i.hasNext())
        {
            QRegularExpressionMatch match = i.next();
            int length = match.capturedLength();
            if (length == 0)
                continue;
            int start = match.capturedStart();
            setFormat(start, length, rule.format);
        }
    }
Пример #12
0
int QzRegExp::indexIn(const QString &str, int offset) const
{
    QzRegExp* that = const_cast<QzRegExp*>(this);
    QRegularExpressionMatch m = match(str, offset);

    if (!m.hasMatch()) {
        that->m_matchedLength = -1;
        that->m_capturedTexts.clear();
        return -1;
    }

    that->m_matchedLength = m.capturedLength();
    that->m_capturedTexts = m.capturedTexts();
    return m.capturedStart();
}
Пример #13
0
bool HRProcessor::test(const Element &, const QString &block)
{
    //! No atomic grouping in python so we simulate it here for performance.
    //! The regex only matches what would be in the atomic group - the HR.
    //! Then check if we are at end of block or if next char is a newline.
    QRegularExpressionMatch m = this->SEARCH_RE.match(block);
    if ( m.hasMatch()
         && ( m.capturedEnd() == block.size()
              || block.at(m.capturedStart()+m.capturedLength()) == '\n' ) ) {
        //! Save match object on class instance so we can use it later.
        this->match = m;
        return true;
    }
    return false;
}
Пример #14
0
bool QuickFindPattern::isLineMatching( const QString& line, int column ) const
{
    if ( ! active_ )
        return false;

    QRegularExpressionMatch match = regexp_.match( line, column );
    if ( match.hasMatch() ) {
        lastMatchStart_ = match.capturedStart();
        lastMatchEnd_ = match.capturedEnd() - 1;
        return true;
    }
    else {
        return false;
    }
}
Пример #15
0
// Handle the specific problem of iframe being self-closed
QString GumboInterface::fix_self_closing_tags(const QString &source)
{
    QString newsource = source;
    QRegularExpression selfclosed("<\\s*iframe(\\s*[^>/]*)/\\s*>");
    QRegularExpressionMatch match = selfclosed.match(newsource, 0);
    while (match.hasMatch()) {
        if (match.capturedStart() == -1) {
            break;
        }
        QString tag = match.captured(0);
        int sp = match.capturedStart(0);
        int n = match.capturedLength(0);
        QString atts = match.captured(1);;
        atts = atts.trimmed();
        if (!atts.isEmpty()) {
            atts = " " + atts;
        }
        QString newtag = "<iframe" + atts + "></iframe>";
        newsource = newsource.replace(sp,n,newtag);
        int nsp = sp + newtag.length();
        match = selfclosed.match(newsource, nsp);
    }
    return newsource;
}
Пример #16
0
static QString replaceInString (const QRegularExpression &rx, QString string, T func) {
	QRegularExpressionMatchIterator it = rx.globalMatch (string);
	
	int offset = 0;
	while (it.hasNext ()) {
		QRegularExpressionMatch match = it.next ();
		QString replaceWith = func (match);
		
		int length = match.capturedLength ();
		int begin = match.capturedStart () + offset;
		string.replace (begin, length, replaceWith);
		offset += replaceWith.length () - length;
	}
	
	return string;
}
Пример #17
0
bool QuickFindPattern::matchLine( const QString& line,
        QList<QuickFindMatch>& matches ) const
{
    matches.clear();

    if ( active_ ) {
        QRegularExpressionMatchIterator matchIterator = regexp_.globalMatch(line);

        while( matchIterator.hasNext() ) {
            QRegularExpressionMatch match = matchIterator.next();
            matches << QuickFindMatch ( match.capturedStart(), match.capturedLength() );
        }
    }

    return ( matches.count() > 0 );
}
Пример #18
0
QString Toolbox::incrementNumberInString(QString string) noexcept {
  QRegularExpression      regex("([0-9]+)(?!.*[0-9]+)");
  QRegularExpressionMatch match = regex.match(string);
  if (match.hasMatch()) {
    // string contains numbers -> increment last number
    bool ok     = false;
    uint number = match.captured().toUInt(&ok);
    if (ok) {
      string.replace(match.capturedStart(), match.capturedLength(),
                     QString::number(number + 1U));
      return string;
    }
  }

  // fallback: just add a "1" at the end
  return string % "1";
}
    bool run(const markdown::Element &parent, QStringList &blocks)
    {
        QString block = blocks.first();
        blocks.pop_front();

        QRegularExpressionMatch m = this->RE.match(block);
        if ( m.hasMatch() ) {
            QString before = block.left(m.capturedStart());  // All lines before direction
            QString after = block.mid(m.capturedEnd());  // All lines after direction
            if ( ! before.isEmpty() ) {
                // As the direction was not the first line of the block and the
                // lines before the direction must be parsed first,
                // recursively parse this lines as a block.
                std::shared_ptr<markdown::BlockParser> parser = this->parser.lock();
                QStringList new_blocks = {before};
                parser->parseBlocks(parent, new_blocks);
            }
            // Create direction
            QString body = m.captured(2);
            // background-image
            m = this->BGIMG_RE.match(body);
            if ( m.hasMatch() ) {
                markdown::Element img = markdown::createSubElement(parent, "img");
                img->attrib["class"] = "background";
                img->attrib["src"] = m.captured(1);
                img->attrib["alt"] = m.captured(2);
            }
            // TODO: other direction
            if ( ! m.hasMatch() ) {
                markdown::Element p = markdown::createSubElement(parent, "p");
                p->attrib["class"] = "comment";
                p->text = body;
            }
            if ( ! after.isEmpty() ) {
                // Insert remaining lines as first block for future parsing.
                blocks.insert(0, after);
            }
            return true;
        } else {
            // This should never happen, but just in case...
            qDebug() << "We've got a problem header: " << block;
            return false;
        }
    }
Пример #20
0
// Returns the largest index of all the Sigil CSS classes
int CleanSource::MaxSigilCSSClassIndex(const QStringList &css_style_tags)
{
    int max_class_index = 0;
    foreach(QString style_tag, css_style_tags) {
        QRegularExpression sigil_class(SIGIL_CLASS_NAME_REG);
        int main_index = 0;

        while (true) {
            QRegularExpressionMatch match = sigil_class.match(style_tag, main_index);
            main_index = match.capturedStart();
            if (main_index == -1) {
                break;
            }

            main_index += match.capturedLength();
            int class_index = match.captured(1).toInt();

            if (class_index > max_class_index) {
                max_class_index = class_index;
            }
        }
    }
Пример #21
0
QStringList WorkbookParserPrivate::splitoutCellReference(QString expression) {
    QStringList result;
    QRegularExpression re = QRegularExpression(REGEX_CELL_REFERENCE_2);
    QRegularExpressionMatch match;
    int start, end = 0;

    QRegularExpressionMatchIterator it = re.globalMatch(expression);
    while (it.hasNext()) {
        match = it.next();
        start = match.capturedStart(0);
        result.append(expression.mid(end, start - end));
        // TODO replace cell references with actual contents of cell
        result.append(match.captured(0));
        // TODO above
        end = match.capturedEnd(0);
    }

    if (end < expression.length())
        result.append(expression.mid(end));

    return result;
}
Пример #22
0
QString TxtFileView::addBoldMarks(QString txtline)
{
    int i=0;
    if(m_isRegEx) {
        QRegularExpressionMatch match;
        while( (match = m_stxtRe.match(txtline, i)).hasMatch() )  {
            txtline.insert(match.capturedEnd(),"</u></b>");
            txtline.insert(match.capturedStart(),"<b><u>");
            i=match.capturedEnd()+6+8;
            m_hits++;
       }
    }
    else {
        while ((i = txtline.indexOf(m_stxt, i, Qt::CaseInsensitive)) != -1) {
            txtline.insert(i+m_stxt.size(),"</u></b>");
            txtline.insert(i,"<b><u>");
            i+=m_stxt.size()+6+8;
            m_hits++;
        }
    }
    return txtline;
}
Пример #23
0
// neither svg nor math tags need a namespace prefix defined
// especially as epub3 now includes them into the html5 spec
// So we need to remove the svg prefix from the tags before
// processing them with gumbo
QString CleanSource::PreprocessSpecialCases(const QString &source)
{
    QString newsource = source;
    // remove prefix from root tag and add unprefixed svg namespace to it
    QRegularExpression root_svg_tag_with_prefix("<\\s*svg\\s*:\\s*svg");
    QString root_svg_embeddedNS = "<svg xmlns=\"http://www.w3.org/2000/svg\"";
    newsource.replace(root_svg_tag_with_prefix, root_svg_embeddedNS);
    // search for any prefixed svg namespace in that root tag and remove it
    QRegularExpression svg_nsprefix(SVG_NAMESPACE_PREFIX);
    QRegularExpressionMatch mo = svg_nsprefix.match(newsource);
    if (mo.hasMatch()) {
        newsource.replace(mo.capturedStart(1), mo.capturedLength(1), "");
    }
    // now strip the prefix from all child starting tags
    QRegularExpression starting_child_svg_tag_with_prefix("<\\s*svg\\s*:");
    QString starting_child_tag_no_prefix = "<";
    newsource.replace(starting_child_svg_tag_with_prefix, starting_child_tag_no_prefix);
    // do the same for any child ending tags
    QRegularExpression ending_child_svg_tag_with_prefix("<\\s*/\\s*svg\\s*:");
    QString ending_child_tag_no_prefix = "</";
    newsource.replace(ending_child_svg_tag_with_prefix, ending_child_tag_no_prefix);
    return newsource;
}
Пример #24
0
std::string GumboInterface::update_style_urls(const std::string &source)
{
    QString result = QString::fromStdString(source);
    // Now parse the text once looking urls and replacing them where needed
    QRegularExpression reference(
        "(?:(?:src|background|background-image|list-style|list-style-image|border-image|border-image-source|content)\\s*:|@import)\\s*"
        "[^;\\}\\(\"']*"
        "(?:"
        "url\\([\"']?([^\\(\\)\"']*)[\"']?\\)"
        "|"
        "[\"']([^\\(\\)\"']*)[\"']"
        ")");
    int start_index = 0;
    QRegularExpressionMatch mo = reference.match(result, start_index);
    do {
        for (int i = 1; i < reference.captureCount(); ++i) {
            if (mo.captured(i).trimmed().isEmpty()) {
                continue;
            }
            QString apath = Utility::URLDecodePath(mo.captured(i));
            QString search_key = QDir::cleanPath(m_currentdir + FORWARD_SLASH + apath);
            QString new_href;
            if (m_sourceupdates.contains(search_key)) {
                new_href = m_sourceupdates.value(search_key);
            }
            if (!new_href.isEmpty()) {
                new_href = Utility::URLEncodePath(new_href);
                result.replace(mo.capturedStart(i), mo.capturedLength(i), new_href);
            }
        }
        start_index += mo.capturedLength();
        mo = reference.match(result, start_index);
    } while (mo.hasMatch());

    return result.toStdString();
}
Пример #25
0
void TCommandLine::handleTabCompletion(bool direction)
{
    if ((mTabCompletionCount < 0) || (mUserKeptOnTyping)) {
        mTabCompletionTyped = toPlainText();
        if (mTabCompletionTyped.size() == 0) {
            return;
        }
        mUserKeptOnTyping = false;
        mTabCompletionCount = -1;
    }
    int amount = mpHost->mpConsole->buffer.size();
    if (amount > 500) {
        amount = 500;
    }

    QStringList bufferList = mpHost->mpConsole->buffer.getEndLines(amount);
    QString buffer = bufferList.join(QChar::Space);

    buffer.replace(QChar(0x21af), QChar::LineFeed);
    buffer.replace(QChar::LineFeed, QChar::Space);

    QStringList wordList = buffer.split(QRegularExpression(QStringLiteral(R"(\b)"), QRegularExpression::UseUnicodePropertiesOption), QString::SkipEmptyParts);
    if (direction) {
        mTabCompletionCount++;
    } else {
        mTabCompletionCount--;
    }
    if (!wordList.empty()) {
        if (mTabCompletionTyped.endsWith(QChar::Space)) {
            return;
        }
        QString lastWord;
        QRegularExpression reg = QRegularExpression(QStringLiteral(R"(\b(\w+)$)"), QRegularExpression::UseUnicodePropertiesOption);
        QRegularExpressionMatch match = reg.match(mTabCompletionTyped);
        int typePosition = match.capturedStart();
        if (reg.captureCount() >= 1) {
            lastWord = match.captured(1);
        } else {
            lastWord = QString();
        }

        QStringList filterList = wordList.filter(QRegularExpression(QStringLiteral(R"(^%1\w+)").arg(lastWord), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption));
        if (filterList.empty()) {
            return;
        }
        int offset = 0;
        for (;;) {
            QString tmp = filterList.back();
            filterList.removeAll(tmp);
            filterList.insert(offset, tmp);
            ++offset;
            if (offset >= filterList.size()) {
                break;
            }
        }

        if (!filterList.empty()) {
            if (mTabCompletionCount >= filterList.size()) {
                mTabCompletionCount = filterList.size() - 1;
            }
            if (mTabCompletionCount < 0) {
                mTabCompletionCount = 0;
            }
            QString proposal = filterList[mTabCompletionCount];
            QString userWords = mTabCompletionTyped.left(typePosition);
            setPlainText(QString(userWords + proposal).trimmed());
            moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
            mTabCompletionOld = toPlainText();
        }
    }
}
Пример #26
0
void Query::buildG2Keywords( QString strPhrase )
{
	QStringList lPositive, lNegative;

	strPhrase = strPhrase.trimmed().replace( "_", " "
											 ).normalized( QString::NormalizationForm_KC
														   ).toLower().append( " " );
	QStringList lWords;
	{
		QRegularExpression re( "(-?\\\".*\\\"|-?\\w+)\\W+",
							   QRegularExpression::InvertedGreedinessOption );
		int nPos = 0, nOldPos = 0;
		bool bHasDash = false;
		QRegularExpressionMatch oMatch;

		while ( ( oMatch = re.match( strPhrase, nPos ) ).hasMatch() )
		{
			nPos = re.match( strPhrase, nPos ).capturedStart();
			QString sWord = oMatch.captured( 1 );

			if ( bHasDash &&
				 nPos - oMatch.capturedLength() - nOldPos == 0 &&
				 lWords.last().size() < 4 &&
				 sWord.size() < 4 )
			{
				lWords.last().append( "-" ).append( sWord );
			}
			else
			{
				lWords << sWord;
			}

			nOldPos = nPos;
			nPos += oMatch.capturedLength();

			if ( strPhrase.mid( nPos - 1, 1 ) == "-" )
			{
				bHasDash = true;
			}
			else
			{
				bHasDash = false;
			}
		}
	}

	lWords.removeDuplicates();

	for ( QStringList::iterator itWord = lWords.begin(); itWord != lWords.end(); )
	{
		if ( ( *itWord ).size() < 4 )
		{
			itWord = lWords.erase( itWord );
		}
		else
		{
			itWord++;
		}
	}

	QRegularExpression rx( "\\w+" );

	foreach ( const QString& sWord, lWords )
	{
		if ( sWord.at( 0 ) == '-' && sWord.at( 1 ) != '"' )
		{
			// plain negative word
			m_sG2NegativeWords.append( sWord.mid( 1 ) ).append( "," );
			lNegative.append( sWord.mid( 1 ) );
		}
		else if ( sWord.at( 0 ) == '"' )
		{
			// positive quoted phrase
			m_sG2PositiveWords.append( sWord ).append( "," );

			// extract words
			int p = 0;
			QRegularExpressionMatch oMatch;
			while ( ( oMatch = rx.match( sWord, p ) ).hasMatch() )
			{
				p = oMatch.capturedStart() + oMatch.capturedLength();
				lPositive.append( oMatch.captured() );
			}
		}
		else if ( sWord.at( 0 ) == '-' && sWord.at( 1 ) == '"' )
		{
			// negative quoted phrase
			m_sG2NegativeWords.append( sWord ).append( "," );

			// extract words
			int p = 0;
			QRegularExpressionMatch oMatch;
			while ( ( oMatch = rx.match( sWord, p ) ).hasMatch() )
			{
				p = oMatch.capturedStart() + oMatch.capturedLength();
				lNegative.append( oMatch.captured() );
			}
		}
		else
		{
			// plain positive word
			m_sG2PositiveWords.append( sWord ).append( "," );
			lPositive.append( sWord );
		}
	}

	m_sG2PositiveWords.chop( 1 );
	m_sG2NegativeWords.chop( 1 );

	foreach( const QString& sWord, lNegative )
	{
		lPositive.removeAll( sWord );
	}
Пример #27
0
void SignalSyntax::highlightBlock(const QString& text)
{
  QTextCharFormat pointFormat;
  pointFormat.setFontWeight(QFont::Normal);
  pointFormat.setForeground(QBrush(QColor(180,182,182)));
  pointFormat.setFont(CodeFont{});

  QTextCharFormat ppointFormat;
  ppointFormat.setFontWeight(QFont::Normal);
  ppointFormat.setForeground(QBrush(QColor(232,117,15)));
  ppointFormat.setFont(CodeFont{});

  QTextCharFormat commaFormat;
  commaFormat.setFontWeight(QFont::Normal);
  commaFormat.setForeground(QBrush(QColor(239,93,61)));
  commaFormat.setFont(CodeFont{});

  
  QRegularExpression countReg("^[0-9]*|\\[[ 0-9]*\\]");
  QRegularExpressionMatchIterator itr = countReg.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), ppointFormat);
  }

  QRegularExpression pointReg("[A-Za-z,\\.:() <>\\[\\]\\_$0-9]*");
  itr = pointReg.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), pointFormat);
  }

  QRegularExpression ppointReg("::[A-Za-z0-9_]*:");
  itr = ppointReg.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), ppointFormat);
  }

  QRegularExpression ppointReg4("[ ]+[A-Za-z0-9_]*:");
  itr = ppointReg4.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), ppointFormat);
  }

  QRegularExpression commaReg("[\\,]*");
  itr = commaReg.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), commaFormat);
  }

  
  QRegularExpression pointReg2("[:]*");
   itr = pointReg2.globalMatch(text);
  while(itr.hasNext()) {
    QRegularExpressionMatch match = itr.next();
    setFormat(match.capturedStart(), match.capturedLength(), pointFormat);
  }
  
  
}
Пример #28
0
void ReplaceMatches::doReplaceNextMatch()
{
    if ((!m_manager) || (m_cancelReplace) || (m_tree->topLevelItemCount() != 1)) {
        m_rootIndex = -1;
        emit replaceDone();
        return;
    }

    // NOTE The document managers signal documentWillBeDeleted() must be connected to
    // cancelReplace(). A closed file could lead to a crash if it is not handled.

    // Open the file
    QTreeWidgetItem *rootItem = m_tree->topLevelItem(0)->child(m_rootIndex);
    if (!rootItem) {
        m_rootIndex = -1;
        emit replaceDone();
        return;
    }

    if (!rootItem->data(0, ColumnRole).toString().isEmpty()) {
        // this is a search as you type replace
        rootItem = m_tree->topLevelItem(0);
        m_cancelReplace = true; // only one document...
    }

    if (rootItem->checkState(0) == Qt::Unchecked) {
        m_rootIndex++;
        emit replaceNextMatch();
        return;
    }

    KTextEditor::Document *doc;
    QString docUrl = rootItem->data(0, FileUrlRole).toString();
    QString docName = rootItem->data(0, FileNameRole).toString();
    if (docUrl.isEmpty()) {
        doc = findNamed(rootItem->data(0, FileNameRole).toString());
    }
    else {
        doc = m_manager->findUrl(QUrl::fromUserInput(docUrl));
        if (!doc) {
            doc = m_manager->openUrl(QUrl::fromUserInput(rootItem->data(0, FileUrlRole).toString()));
        }
    }

    if (!doc) {
        m_rootIndex++;
        emit replaceNextMatch();
        return;
    }

    QVector<KTextEditor::MovingRange*> rVector;
    QStringList rTexts;
    KTextEditor::MovingInterface* miface = qobject_cast<KTextEditor::MovingInterface*>(doc);
    int line;
    int column;
    int matchLen;
    int endLine;
    int endColumn;
    QTreeWidgetItem *item;
    QString matchLines;

    // lines might be modified so search the document again
    for (int i=0; i<rootItem->childCount(); i++) {
        item = rootItem->child(i);
        if (item->checkState(0) == Qt::Unchecked) continue;

        line = endLine= item->data(0, LineRole).toInt();
        column = item->data(0, ColumnRole).toInt();
        matchLen = item->data(0, MatchLenRole).toInt();
        matchLines = doc->line(line).mid(column);
        while (matchLines.size() < matchLen) {
            if (endLine+1 >= doc->lines()) break;
            endLine++;
            matchLines+= QLatin1Char('\n') + doc->line(endLine);
        }

        QRegularExpressionMatch match = m_regExp.match(matchLines);
        if (match.capturedStart() != 0) {
            qDebug() << matchLines << "Does not match" << m_regExp.pattern();
            continue;
        }

        QString replaceText = m_replaceText;
        replaceText.replace(QStringLiteral("\\\\"), QStringLiteral("¤Search&Replace¤"));

        // allow captures \0 .. \9
        for (int j = qMin(9, match.lastCapturedIndex()); j >= 0; --j) {
            replaceText.replace(QString(QStringLiteral("\\%1")).arg(j), match.captured(j));
        }

        // allow captures \{0} .. \{9999999}...
        for (int j = match.lastCapturedIndex(); j >= 0; --j) {
            replaceText.replace(QString(QStringLiteral("\\{%1}")).arg(j), match.captured(j));
        }

        replaceText.replace(QStringLiteral("\\n"), QStringLiteral("\n"));
        replaceText.replace(QStringLiteral("\\t"), QStringLiteral("\t"));
        replaceText.replace(QStringLiteral("¤Search&Replace¤"), QStringLiteral("\\"));
        rTexts << replaceText;

        replaceText.replace(QLatin1Char('\n'), QStringLiteral("\\n"));
        replaceText.replace(QLatin1Char('\t'), QStringLiteral("\\t"));
        QString html = item->data(0, PreMatchRole).toString();
        html += QStringLiteral("<i><s>") + item->data(0, MatchRole).toString() + QStringLiteral("</s></i> ");
        html += QStringLiteral("<b>") + replaceText + QStringLiteral("</b>");
        html += item->data(0, PostMatchRole).toString();
        item->setData(0, Qt::DisplayRole, i18n("Line: <b>%1</b>: %2",line+1, html));

        endLine = line;
        endColumn = column+matchLen;
        while ((endLine < doc->lines()) &&  (endColumn > doc->line(endLine).size())) {
            endColumn -= doc->line(endLine).size();
            endColumn--; // remove one for '\n'
            endLine++;
        }
        KTextEditor::Range range(line, column, endLine, endColumn);
        KTextEditor::MovingRange* mr = miface->newMovingRange(range);
        rVector.append(mr);
    }

    for (int i=0; i<rVector.size(); i++) {
        line = rVector[i]->start().line();
        column = rVector[i]->start().column();
        doc->replaceText(*rVector[i], rTexts[i]);
        emit matchReplaced(doc, line, column, rTexts[i].length());
    }

    qDeleteAll(rVector);

    m_rootIndex++;
    emit replaceNextMatch();
}
Пример #29
0
	void readInlineText(const QString &data)
	{
		QString line = data;
		// remove all but one space on the front
		{
			bool startedWithSpace = line.startsWith(' ');
			line = line.remove(QRegularExpression("^ *"));
			if (startedWithSpace)
			{
				line = " " + line;
			}
		}
		// inline code
		{
			QRegularExpression exp("`(.*)`");
			QRegularExpressionMatch match = exp.match(line);
			while (match.hasMatch())
			{
				codeSections.append(match.captured(1));
				line.replace(match.capturedStart(), match.capturedLength(), QString("$${{%1}}$$").arg(codeSections.size() - 1));
				match = exp.match(line);
			}
		}
		// link and image
		{
			QRegularExpression exp("(\\!?)\\[(.*)\\]\\((.*)\\)");
			QRegularExpressionMatch match = exp.match(line);
			while (match.hasMatch())
			{
				if (match.captured(1) == "!")
				{
					// FIXME this no work
					htmlSections.append(QString("<img src=\"%1\" alt=\"%2\"/>").arg(match.captured(3), match.captured(2)));
				}
				else
				{
					htmlSections.append(QString("<a href=\"%1\">%2</a>").arg(match.captured(3), match.captured(2)));
				}
				line.replace(match.capturedStart(), match.capturedLength(), QString("$$[[%1]]$$").arg(htmlSections.size() - 1));
				match = exp.match(line);
			}
		}
		QTextCharFormat fmt;
		int numStarsOrUnderscores = 0;
		QChar last = 0;
		for (const QChar &c : line)
		{
			if (last != c)
			{
				// bold
				if (numStarsOrUnderscores == 2)
				{
					if (fmt.fontWeight() == QFont::Normal)
					{
						fmt.setFontWeight(QFont::Bold);
					}
					else
					{
						fmt.setFontWeight(QFont::Normal);
					}
				}
				// italic
				else if (numStarsOrUnderscores == 1)
				{
					fmt.setFontItalic(!fmt.fontItalic());
				}
				numStarsOrUnderscores = 0;
				cursor.setCharFormat(fmt);
			}
			last = c;
			if (c == '*' || c == '_')
			{
				numStarsOrUnderscores++;
			}
			else
			{
				cursor.insertText(c);
			}
		}
	}
Пример #30
0
void FlatTextarea::parseLinks() { // some code is duplicated in text.cpp!
	LinkRanges newLinks;

	QString text(toPlainText());
	if (text.isEmpty()) {
		if (!_links.isEmpty()) {
			_links.clear();
			emit linksChanged();
		}
		return;
	}

	initLinkSets();

	int32 len = text.size();
	const QChar *start = text.unicode(), *end = start + text.size();
	for (int32 offset = 0, matchOffset = offset; offset < len;) {
		QRegularExpressionMatch m = reDomain().match(text, matchOffset);
		if (!m.hasMatch()) break;

		int32 domainOffset = m.capturedStart();

		QString protocol = m.captured(1).toLower();
		QString topDomain = m.captured(3).toLower();

		bool isProtocolValid = protocol.isEmpty() || validProtocols().contains(hashCrc32(protocol.constData(), protocol.size() * sizeof(QChar)));
		bool isTopDomainValid = !protocol.isEmpty() || validTopDomains().contains(hashCrc32(topDomain.constData(), topDomain.size() * sizeof(QChar)));

		if (protocol.isEmpty() && domainOffset > offset + 1 && *(start + domainOffset - 1) == QChar('@')) {
			QString forMailName = text.mid(offset, domainOffset - offset - 1);
			QRegularExpressionMatch mMailName = reMailName().match(forMailName);
			if (mMailName.hasMatch()) {
				offset = matchOffset = m.capturedEnd();
				continue;
			}
		}
		if (!isProtocolValid || !isTopDomainValid) {
			offset = matchOffset = m.capturedEnd();
			continue;
		}

		QStack<const QChar*> parenth;
		const QChar *domainEnd = start + m.capturedEnd(), *p = domainEnd;
		for (; p < end; ++p) {
			QChar ch(*p);
			if (chIsLinkEnd(ch)) break; // link finished
			if (chIsAlmostLinkEnd(ch)) {
				const QChar *endTest = p + 1;
				while (endTest < end && chIsAlmostLinkEnd(*endTest)) {
					++endTest;
				}
				if (endTest >= end || chIsLinkEnd(*endTest)) {
					break; // link finished at p
				}
				p = endTest;
				ch = *p;
			}
			if (ch == '(' || ch == '[' || ch == '{' || ch == '<') {
				parenth.push(p);
			} else if (ch == ')' || ch == ']' || ch == '}' || ch == '>') {
				if (parenth.isEmpty()) break;
				const QChar *q = parenth.pop(), open(*q);
				if ((ch == ')' && open != '(') || (ch == ']' && open != '[') || (ch == '}' && open != '{') || (ch == '>' && open != '<')) {
					p = q;
					break;
				}
			}
		}
		if (p > domainEnd) { // check, that domain ended
			if (domainEnd->unicode() != '/' && domainEnd->unicode() != '?') {
				matchOffset = domainEnd - start;
				continue;
			}
		}
		newLinks.push_back(qMakePair(domainOffset - 1, p - start - domainOffset + 2));
		offset = matchOffset = p - start;
	}

	if (newLinks != _links) {
		_links = newLinks;
		emit linksChanged();
	}
}