Changeset View
Changeset View
Standalone View
Standalone View
src/kuitmarkup.cpp
Show First 20 Lines • Show All 1581 Lines • ▼ Show 20 Line(s) | |||||
1582 | } | 1582 | } | ||
1583 | 1583 | | |||
1584 | QString KuitFormatterPrivate::salvageMarkup(const QString &text_, | 1584 | QString KuitFormatterPrivate::salvageMarkup(const QString &text_, | ||
1585 | Kuit::VisualFormat format, | 1585 | Kuit::VisualFormat format, | ||
1586 | const KuitSetup &setup) const | 1586 | const KuitSetup &setup) const | ||
1587 | { | 1587 | { | ||
1588 | QString text = text_; | 1588 | QString text = text_; | ||
1589 | QString ntext; | 1589 | QString ntext; | ||
1590 | int pos; | | |||
1591 | 1590 | | |||
1592 | // Resolve tags simple-mindedly. | 1591 | // Resolve tags simple-mindedly. | ||
1593 | 1592 | | |||
1594 | // - tags with content | 1593 | // - tags with content | ||
1595 | static QRegExp staticWrapRx(QStringLiteral("(<\\s*(\\w+)\\b([^>]*)>)(.*)(<\\s*/\\s*\\2\\s*>)")); | 1594 | static const QRegularExpression wrapRx(QStringLiteral("(<\\s*(\\w+)\\b([^>]*)>)(.*)(<\\s*/\\s*\\2\\s*>)"), | ||
1596 | QRegExp wrapRx = staticWrapRx; // QRegExp not thread-safe | 1595 | QRegularExpression::InvertedGreedinessOption); | ||
1597 | wrapRx.setMinimal(true); | 1596 | QRegularExpressionMatchIterator iter = wrapRx.globalMatch(text); | ||
1598 | pos = 0; | 1597 | QRegularExpressionMatch match; | ||
1599 | //ntext.clear(); | 1598 | int pos = 0; | ||
1600 | while (true) { | 1599 | while (iter.hasNext()) { | ||
1601 | int previousPos = pos; | 1600 | match = iter.next(); | ||
1602 | pos = wrapRx.indexIn(text, previousPos); | 1601 | ntext += text.midRef(pos, match.capturedStart(0) - pos); | ||
1603 | if (pos < 0) { | 1602 | const QString tagname = match.captured(2).toLower(); | ||
1604 | ntext += text.midRef(previousPos); | 1603 | const QString content = salvageMarkup(match.captured(4), format, setup); | ||
1605 | break; | | |||
1606 | } | | |||
1607 | ntext += text.midRef(previousPos, pos - previousPos); | | |||
1608 | const QStringList capts = wrapRx.capturedTexts(); | | |||
1609 | QString tagname = capts[2].toLower(); | | |||
1610 | QString content = salvageMarkup(capts[4], format, setup); | | |||
1611 | if (setup.d->knownTags.contains(tagname)) { | 1604 | if (setup.d->knownTags.contains(tagname)) { | ||
1612 | const KuitTag &tag = setup.d->knownTags.value(tagname); | 1605 | const KuitTag &tag = setup.d->knownTags.value(tagname); | ||
1613 | QHash<QString, QString> attributes; | 1606 | QHash<QString, QString> attributes; | ||
1614 | // TODO: Do not ignore attributes (in capts[3]). | 1607 | // TODO: Do not ignore attributes (in match.captured(3)). | ||
1615 | ntext += tag.format(languageAsList, | 1608 | ntext += tag.format(languageAsList, | ||
1616 | attributes, content, | 1609 | attributes, content, | ||
1617 | QStringList(), format); | 1610 | QStringList(), format); | ||
1618 | } else { | 1611 | } else { | ||
1619 | ntext += capts[1] + content + capts[5]; | 1612 | ntext += match.captured(1) + content + match.captured(5); | ||
1620 | } | 1613 | } | ||
1621 | pos += wrapRx.matchedLength(); | 1614 | pos = match.capturedEnd(0); | ||
1622 | } | 1615 | } | ||
1616 | // get the remaining part after the last match in "text" | ||||
1617 | ntext += text.midRef(pos); | ||||
1623 | text = ntext; | 1618 | text = ntext; | ||
1624 | 1619 | | |||
1625 | // - tags without content | 1620 | // - tags without content | ||
1626 | static QRegExp staticNowrRx(QStringLiteral("<\\s*(\\w+)\\b([^>]*)/\\s*>")); | 1621 | static const QRegularExpression nowrRx(QStringLiteral("<\\s*(\\w+)\\b([^>]*)/\\s*>"), | ||
1627 | QRegExp nowrRx = staticNowrRx; // QRegExp not thread-safe | 1622 | QRegularExpression::InvertedGreedinessOption); | ||
1628 | nowrRx.setMinimal(true); | 1623 | iter = nowrRx.globalMatch(text); | ||
1629 | pos = 0; | 1624 | pos = 0; | ||
1630 | ntext.clear(); | 1625 | ntext.clear(); | ||
1631 | while (true) { | 1626 | while (iter.hasNext()) { | ||
1632 | int previousPos = pos; | 1627 | match = iter.next(); | ||
1633 | pos = nowrRx.indexIn(text, previousPos); | 1628 | ntext += text.midRef(pos, match.capturedStart(0) - pos); | ||
1634 | if (pos < 0) { | 1629 | const QString tagname = match.captured(1).toLower(); | ||
1635 | ntext += text.midRef(previousPos); | | |||
1636 | break; | | |||
1637 | } | | |||
1638 | ntext += text.midRef(previousPos, pos - previousPos); | | |||
1639 | const QStringList capts = nowrRx.capturedTexts(); | | |||
1640 | QString tagname = capts[1].toLower(); | | |||
1641 | if (setup.d->knownTags.contains(tagname)) { | 1630 | if (setup.d->knownTags.contains(tagname)) { | ||
1642 | const KuitTag &tag = setup.d->knownTags.value(tagname); | 1631 | const KuitTag &tag = setup.d->knownTags.value(tagname); | ||
1643 | ntext += tag.format(languageAsList, | 1632 | ntext += tag.format(languageAsList, | ||
1644 | QHash<QString, QString>(), QString(), | 1633 | QHash<QString, QString>(), QString(), | ||
1645 | QStringList(), format); | 1634 | QStringList(), format); | ||
1646 | } else { | 1635 | } else { | ||
1647 | ntext += capts[0]; | 1636 | ntext += match.captured(0); | ||
1648 | } | 1637 | } | ||
1649 | pos += nowrRx.matchedLength(); | 1638 | pos = match.capturedEnd(0); | ||
1650 | } | 1639 | } | ||
1640 | // get the remaining part after the last match in "text" | ||||
1641 | ntext += text.midRef(pos); | ||||
1651 | text = ntext; | 1642 | text = ntext; | ||
1652 | 1643 | | |||
1653 | // Add top tag. | 1644 | // Add top tag. | ||
1654 | if (format == Kuit::RichText) { | 1645 | if (format == Kuit::RichText) { | ||
1655 | text = QStringLiteral("<html>") + text + QStringLiteral("</html>"); | 1646 | text = QStringLiteral("<html>") + text + QStringLiteral("</html>"); | ||
1656 | } | 1647 | } | ||
1657 | 1648 | | |||
1658 | return text; | 1649 | return text; | ||
Show All 18 Lines |