diff --git a/autotests/texthandlertest.cpp b/autotests/texthandlertest.cpp index 69cb7cf75..7f2148304 100644 --- a/autotests/texthandlertest.cpp +++ b/autotests/texthandlertest.cpp @@ -43,8 +43,8 @@ private Q_SLOTS: void sendCustomEmoji(); void sendCustomEmojiCode_data(); void sendCustomEmojiCode(); - void sendSpoilerTags_data(); - void sendSpoilerTags(); + void sendCustomTags_data(); + void sendCustomTags(); void receiveSpacelessSelfClosingTag(); void receiveStripReply(); @@ -251,20 +251,28 @@ void TextHandlerTest::sendCustomEmojiCode() QCOMPARE(testTextHandler.handleSendText(), testOutputString); } -void TextHandlerTest::sendSpoilerTags_data() +void TextHandlerTest::sendCustomTags_data() { QTest::addColumn("testInputString"); QTest::addColumn("testOutputString"); - QTest::newRow("incomplete") << u"||test"_s << u"||test"_s; - QTest::newRow("complete") << u"||test||"_s << u"test"_s; - QTest::newRow("multiple") << u"||apple||banana||pear||"_s << u"applebananapear"_s; - QTest::newRow("inside code block") << u"```||apple||```"_s << u"||apple||"_s; - QTest::newRow("outside code block") << u"||apple|| ```||banana||``` ||pear||"_s - << u"apple ||banana|| pear"_s; + // spoiler + QTest::newRow("incomplete spoiler") << u"||test"_s << u"||test"_s; + QTest::newRow("complete spoiler") << u"||test||"_s << u"test"_s; + QTest::newRow("multiple spoiler") << u"||apple||banana||pear||"_s << u"applebananapear"_s; + QTest::newRow("inside code block spoiler") << u"```||apple||```"_s << u"||apple||"_s; + QTest::newRow("outside code block spoiler") << u"||apple|| ```||banana||``` ||pear||"_s + << u"apple ||banana|| pear"_s; + + // strikethrough + QTest::newRow("incomplete strikethrough") << u"~~test"_s << u"~~test"_s; + QTest::newRow("complete strikethrough") << u"~~test~~"_s << u"test"_s; + QTest::newRow("inside code block strikethrough") << u"```~~apple~~```"_s << u"~~apple~~"_s; + QTest::newRow("outside code block strikethrough") << u"~~apple~~ ```~~banana~~``` ~~pear~~"_s + << u"apple ~~banana~~ pear"_s; } -void TextHandlerTest::sendSpoilerTags() +void TextHandlerTest::sendCustomTags() { QFETCH(QString, testInputString); QFETCH(QString, testOutputString); diff --git a/src/libneochat/texthandler.cpp b/src/libneochat/texthandler.cpp index 6525fb8e7..9ac878209 100644 --- a/src/libneochat/texthandler.cpp +++ b/src/libneochat/texthandler.cpp @@ -706,45 +706,53 @@ QString TextHandler::customMarkdownToHtml(const QString &stringIn) { QString buffer = stringIn; - qsizetype beginCodeBlockTag = buffer.indexOf(u""_s); - qsizetype endCodeBlockTag = buffer.indexOf(u""_s, beginCodeBlockTag + 1); + const auto processSyntax = [&buffer](const QString &syntax, const QString &beginTag, const QString &endTag) { + qsizetype beginCodeBlockTag = buffer.indexOf(u""_s); + qsizetype endCodeBlockTag = buffer.indexOf(u""_s, beginCodeBlockTag + 1); - // Indesx to search from - qsizetype lastPos = 0; - while (true) { - const qsizetype pos = buffer.indexOf(u"||"_s, lastPos); - if (pos == -1) { - break; + // Index to search from + qsizetype lastPos = 0; + while (true) { + const qsizetype pos = buffer.indexOf(syntax, lastPos); + if (pos == -1) { + break; + } + + // If we're inside a code block, ignore and move the search past the code block + const bool validCodeBlock = beginCodeBlockTag != -1 && endCodeBlockTag != -1; + if (validCodeBlock && pos > beginCodeBlockTag && pos < endCodeBlockTag) { + lastPos = endCodeBlockTag + 5; + continue; + } + + qsizetype nextPos = buffer.indexOf(syntax, pos + 1); + if (nextPos == -1) { + break; + } + + // Replace the beginning syntax + buffer.replace(pos, 2, beginTag); + + // Update positions and re-search since the underlying text buffer changed + nextPos = buffer.indexOf(syntax, pos + 1); + beginCodeBlockTag = buffer.indexOf(u""_s, pos + 1); + endCodeBlockTag = buffer.indexOf(u""_s, beginCodeBlockTag + 1); + + // Now replace the end syntax + buffer.replace(nextPos, 2, endTag); + + // Move the search pointer past this point. + // Not technically needed in most cases since we replaced the original tag, but needed for code blocks + // which still have the characters. + lastPos = nextPos + 2; } + }; - // If we're inside of a code block, ignore and move the search past the code block - const bool validCodeBlock = beginCodeBlockTag != -1 && endCodeBlockTag != -1; - if (validCodeBlock && pos > beginCodeBlockTag && pos < endCodeBlockTag) { - lastPos = endCodeBlockTag + 5; - continue; - } + // spoilers + processSyntax(u"||"_s, u""_s, u""_s); - qsizetype nextPos = buffer.indexOf(u"||"_s, pos + 1); - if (nextPos == -1) { - break; - } - - // Replace the begin || - buffer.replace(pos, 2, QStringLiteral("")); - - // Update positions and re-search since the underlying text buffer changed - nextPos = buffer.indexOf(u"||"_s, pos + 1); - beginCodeBlockTag = buffer.indexOf(u""_s, pos + 1); - endCodeBlockTag = buffer.indexOf(u""_s, beginCodeBlockTag + 1); - - // Now replace the end || - buffer.replace(nextPos, 2, QStringLiteral("")); - - // Move the search pointer past this point. - // Not technically needed in most cases since we replaced the original tag, but needed for code blocks - // which still have the characters. - lastPos = nextPos + 2; - } + // strikethrough + processSyntax(u"~~"_s, u""_s, u""_s); return buffer; }