예제 #1
0
QString LayerListModel::getAvailableLayerName(QString basename) const
{
	// Return a layer name of format "basename n" where n is one bigger than the
	// biggest suffix number of layers named "basename n".

	// First, strip suffix number from the basename (if it exists)

	QRegularExpression suffixNumRe("(\\d+)$");
	{
		auto m = suffixNumRe.match(basename);
		if(m.hasMatch()) {
			basename = basename.mid(0, m.capturedStart()).trimmed();
		}
	}

	// Find the biggest suffix in the layer stack
	int suffix = 0;
	for(const LayerListItem &l : _items) {
		auto m = suffixNumRe.match(l.title);
		if(m.hasMatch()) {
			if(l.title.startsWith(basename)) {
				suffix = qMax(suffix, m.captured(1).toInt());
			}
		}
	}

	// Make unique name
	return QString("%2 %1").arg(suffix+1).arg(basename);
}
예제 #2
0
파일: syntax.cpp 프로젝트: PhE/antimony
void SyntaxHighlighter::highlightBlock(const QString& text)
{
    for (auto r : rules)
    {
        auto iter = r.first.globalMatch(text);
        while (iter.hasNext())
        {
            auto match = iter.next();
            auto index = match.lastCapturedIndex();
            setFormat(match.capturedStart(index),
                      match.capturedLength(index),
                      r.second);
        }
    }
}
예제 #3
0
/**
 * @brief prepend the match string with specify symbol
 * @param input string need to prepend symbol
 * @param number_length the length of the number, will prepend symbol
 * if the length smaller than this number
 * @param symbol symbol prepand before the number
 * @return the name after alter
 * @example ex : number_length == 3, reg = (\\d+), symbol = '0'
 * then "1" == "001", "10" == "010"
 * ex : number_length == 2, reg = (\\d+), symbol = '0'
 * then "1" == "01", "10" == "10"
 */
QString prepend_symbol_on_match(QString const &input, int number_length,
                                QRegularExpression const &reg,
                                QChar symbol)
{    
    auto new_file_name = input;
    auto match = reg.match(new_file_name);

    if(match.hasMatch()){
        auto const Captured = match.captured(0);
        if(Captured.size() < number_length){
            new_file_name.insert(match.capturedStart(0),
                                 QString(number_length - match.capturedLength(1),
                                         symbol));
        }
    }

    return new_file_name;
}
예제 #4
0
KTextEditor::Cursor KTextEditorHelpers::extractCursor(const QString& input, int* pathLength)
{
    static const QRegularExpression pattern(QStringLiteral(":(\\d+)(?::(\\d+))?$"));
    const auto match = pattern.match(input);
    if (!match.hasMatch()) {
        if (pathLength)
            *pathLength = input.length();
        return KTextEditor::Cursor::invalid();
    }

    int line = match.capturedRef(1).toInt() - 1;
    // don't use an invalid column when the line is valid
    int column = qMax(0, match.captured(2).toInt() - 1);

    if (pathLength)
        *pathLength = match.capturedStart(0);
    return {line, column};
}
예제 #5
0
void ItemSourceHighlighter::highlightBlock(const QString& text)
{
   //
   // Apply matching highlighting rules.
   //

   for (const auto& rule : rules_)
   {
      for (const auto& expression : rule.expressions)
      {
         auto matches = expression.globalMatch(text);
         while (matches.hasNext() == true)
         {
            auto match = matches.next();

            setFormat(match.capturedStart(1), match.capturedLength(1), rule.format);
         }
      }
   }
}
예제 #6
0
const QString clearHTMLTags(const QString &text)
{
    const QRegularExpression regex("<(\\w+)[^>]*>([^<]*)</\\1>");

    QString ret = text;
    do
    {
        const auto match = regex.match(ret);
        if (!match.isValid() || !match.hasMatch())
            break;

        const int start = match.capturedStart();
        const int len = match.capturedLength();
        const QString &cap = match.captured(2);

        ret.replace(start, len, cap);
    } while (true);

    return ret;
}
예제 #7
0
QString linkify(const QString &input)
{
	// This regular expression is from: http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the
	static const QRegularExpression linkre(
		"((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]+|(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)[A-Za-z0-9\\.\\-]+)((?:\\/[\\+~%\\/\\.\\w\\-_]*)?\\?" "?(?:[\\-\\+=&;%@\\.\\w_]*)#?(?:[\\.\\!\\/\\\\\\w]*))?)"
		);

	static const QRegularExpression protore("^[a-zA-Z]{3,}:");

	auto matches = linkre.globalMatch(input);
	QString out;
	int pos=0;

	while(matches.hasNext()) {
		auto m = matches.next();
		QString url = m.captured();
		out.append(input.midRef(pos, m.capturedStart() - pos));
		pos = m.capturedEnd();

		out.append("<a href=\"");
		if(!protore.match(url).hasMatch())
			out.append("http://");
		out.append(url);
		out.append("\">");
		out.append(url);
		out.append("</a>");
	}

	// special case optimization: no matches
	if(pos==0)
		return input;

	out.append(input.midRef(pos));

	return out;
}
예제 #8
0
void MessageLinksParser::parse() {
	const auto &textWithTags = _field->getTextWithTags();
	const auto &text = textWithTags.text;
	const auto &tags = textWithTags.tags;
	const auto &markdownTags = _field->getMarkdownTags();
	if (text.isEmpty()) {
		_list = QStringList();
		return;
	}

	auto ranges = QVector<LinkRange>();

	auto tag = tags.begin();
	const auto tagsEnd = tags.end();
	const auto processTag = [&] {
		Expects(tag != tagsEnd);

		if (Ui::InputField::IsValidMarkdownLink(tag->id)
			&& !IsMentionLink(tag->id)) {
			ranges.push_back({ tag->offset, tag->length, tag->id });
		}
		++tag;
	};
	const auto processTagsBefore = [&](int offset) {
		while (tag != tagsEnd && tag->offset + tag->length <= offset) {
			processTag();
		}
	};
	const auto hasTagsIntersection = [&](int till) {
		if (tag == tagsEnd || tag->offset >= till) {
			return false;
		}
		while (tag != tagsEnd && tag->offset < till) {
			processTag();
		}
		return true;
	};

	auto markdownTag = markdownTags.begin();
	const auto markdownTagsEnd = markdownTags.end();
	const auto markdownTagsAllow = [&](int from, int length) {
		while (markdownTag != markdownTagsEnd
			&& (markdownTag->adjustedStart
				+ markdownTag->adjustedLength <= from
				|| !markdownTag->closed)) {
			++markdownTag;
			continue;
		}
		if (markdownTag == markdownTagsEnd
			|| markdownTag->adjustedStart >= from + length) {
			return true;
		}
		// Ignore http-links that are completely inside some tags.
		// This will allow sending http://test.com/__test__/test correctly.
		return (markdownTag->adjustedStart > from)
			|| (markdownTag->adjustedStart
				+ markdownTag->adjustedLength < from + length);
	};

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

		auto domainOffset = m.capturedStart();

		auto protocol = m.captured(1).toLower();
		auto topDomain = m.captured(3).toLower();
		auto isProtocolValid = protocol.isEmpty() || TextUtilities::IsValidProtocol(protocol);
		auto isTopDomainValid = !protocol.isEmpty() || TextUtilities::IsValidTopDomain(topDomain);

		if (protocol.isEmpty() && domainOffset > offset + 1 && *(start + domainOffset - 1) == QChar('@')) {
			auto forMailName = text.mid(offset, domainOffset - offset - 1);
			auto mMailName = TextUtilities::RegExpMailNameAtEnd().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;
			}
		}
		const auto range = LinkRange {
			domainOffset,
			static_cast<int>(p - start - domainOffset),
			QString()
		};
		processTagsBefore(domainOffset);
		if (!hasTagsIntersection(range.start + range.length)) {
			if (markdownTagsAllow(range.start, range.length)) {
				ranges.push_back(range);
			}
		}
		offset = matchOffset = p - start;
	}
	processTagsBefore(QFIXED_MAX);

	apply(text, ranges);
}