File indexing completed on 2024-05-05 04:42:43

0001 /*
0002     SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "notesutil_p.h"
0008 
0009 #include <QRegularExpression>
0010 #include <QString>
0011 #include <QStringList>
0012 
0013 using namespace KPublicTransport;
0014 
0015 
0016 QString NotesUtil::normalizeNote(const QString &note)
0017 {
0018     auto n = note;
0019     n.replace(QLatin1String("&nbsp;"), QLatin1String(" "));
0020     n.replace(QLatin1String("  "), QLatin1String(" "));
0021 
0022     if (!note.contains(QLatin1String("href"))) { // only mess with rich text if this isn't marked up already
0023         static QRegularExpression linkRegExp(QStringLiteral("(?:https?://)?(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(:?/[^ \"<>]+)?"));
0024         const auto match = linkRegExp.match(n);
0025         if (match.hasMatch()) {
0026             n.replace(match.capturedStart(), match.capturedLength(), QLatin1String("<a href=\"")
0027                 + (match.capturedView().startsWith(QLatin1String("http")) ? QString() : QStringLiteral("https://"))
0028                 + match.capturedView()
0029                 + QLatin1String("\">") + match.capturedView() + QLatin1String("</a>"));
0030         }
0031     }
0032 
0033     // strip <span> tags
0034     static QRegularExpression spanExp(QStringLiteral("</?span[^>]*>"));
0035     n.remove(spanExp);
0036     static QRegularExpression styleAttrExp(QStringLiteral(" style=\"[^>\"]*\""));
0037     n.remove(styleAttrExp);
0038 
0039     // clean up extra line breaks and empty paragraphs
0040     static QRegularExpression consecutiveBrExp(QStringLiteral("<br[^>]*> *(?:<br[^>]*>|\n)"));
0041     while (n.contains(consecutiveBrExp)) {
0042         n.replace(consecutiveBrExp, QStringLiteral("<br/>"));
0043     }
0044     static QRegularExpression leadinBrExp(QStringLiteral("<p> *<br[^>]*>"));
0045     static QRegularExpression trailingBrExp(QStringLiteral("<br[^>]*> *</p>"));
0046     static QRegularExpression trailingBrExp2(QStringLiteral("<br[^>]*> *<p>"));
0047     n.replace(leadinBrExp, QStringLiteral("<p>"));
0048     n.replace(trailingBrExp, QStringLiteral("</p>"));
0049     n.replace(trailingBrExp2, QStringLiteral("<p>"));
0050     static QRegularExpression emptyParaExp(QStringLiteral("<p> *</p>"));
0051     n.remove(emptyParaExp);
0052 
0053     return n.trimmed();
0054 }
0055 
0056 int NotesUtil::needsAdding(const QStringList &notes, const QString &note)
0057 {
0058     if (note.isEmpty()) {
0059         return -1;
0060     }
0061 
0062     for (auto it = notes.begin(); it != notes.end(); ++it) {
0063         if ((*it).contains(note)) {
0064             return -1;
0065         }
0066         if (note.contains(*it)) {
0067             return std::distance(notes.begin(), it);
0068         }
0069     }
0070 
0071     return notes.size();
0072 }
0073 
0074 void NotesUtil::performAdd(QStringList &notes, const QString &note, int index)
0075 {
0076     if (index < 0) {
0077         return;
0078     }
0079     if (index >= notes.size()) {
0080         notes.push_back(note);
0081     } else {
0082         notes[index] = note;
0083     }
0084 }
0085 
0086 QStringList NotesUtil::mergeNotes(const QStringList &lhs, const QStringList &rhs)
0087 {
0088     if (lhs.isEmpty()) {
0089         return rhs;
0090     }
0091     if (rhs.isEmpty()) {
0092         return lhs;
0093     }
0094 
0095     auto res = lhs;
0096     for (const auto &r : rhs) {
0097         const auto idx = NotesUtil::needsAdding(res, r);
0098         if (idx >= 0) {
0099             NotesUtil::performAdd(res, r, idx);
0100         }
0101     }
0102     return res;
0103 }