diff --git a/autotests/texthandlertest.cpp b/autotests/texthandlertest.cpp index 7b90b0023..69cb7cf75 100644 --- a/autotests/texthandlertest.cpp +++ b/autotests/texthandlertest.cpp @@ -259,6 +259,9 @@ void TextHandlerTest::sendSpoilerTags_data() 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; } void TextHandlerTest::sendSpoilerTags() diff --git a/src/libneochat/texthandler.cpp b/src/libneochat/texthandler.cpp index 35384dda3..6525fb8e7 100644 --- a/src/libneochat/texthandler.cpp +++ b/src/libneochat/texthandler.cpp @@ -706,22 +706,44 @@ QString TextHandler::customMarkdownToHtml(const QString &stringIn) { QString buffer = stringIn; + qsizetype beginCodeBlockTag = buffer.indexOf(u""_s); + qsizetype endCodeBlockTag = buffer.indexOf(u""_s, beginCodeBlockTag + 1); + + // Indesx to search from + qsizetype lastPos = 0; while (true) { - const int pos = buffer.indexOf(u"||"_s); + const qsizetype pos = buffer.indexOf(u"||"_s, lastPos); if (pos == -1) { break; } - int nextPos = buffer.indexOf(u"||"_s, pos + 1); + // 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; + } + + qsizetype nextPos = buffer.indexOf(u"||"_s, pos + 1); if (nextPos == -1) { break; } + // Replace the begin || buffer.replace(pos, 2, QStringLiteral("")); - // we have to re-search because the index moved! + // 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; } return buffer;