Skip to content

Commit 9fc57ad

Browse files
committed
Add custom syntax for tagging spoilers
Currently the only two ways to spoiler text in your message is either: * Using the /spoiler command * Manually typing the data-mx-spoiler span HTML blocks Neither one is discoverable, or friendly to users really. Instead, we should extend our existing Markdown-based formatting syntax with one that can handle spoiler tags. I chose the || syntax to match Discord, since Element doesn't seem to adopt one. Unfortunately, CMark does not support custom extensions (see commonmark/cmark#123) so we have to implement our own parsing function. New tests are also added for this too.
1 parent f329e20 commit 9fc57ad

3 files changed

Lines changed: 50 additions & 0 deletions

File tree

autotests/texthandlertest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private Q_SLOTS:
4343
void sendCustomEmoji();
4444
void sendCustomEmojiCode_data();
4545
void sendCustomEmojiCode();
46+
void sendSpoilerTags_data();
47+
void sendSpoilerTags();
4648

4749
void receiveSpacelessSelfClosingTag();
4850
void receiveStripReply();
@@ -249,6 +251,27 @@ void TextHandlerTest::sendCustomEmojiCode()
249251
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
250252
}
251253

254+
void TextHandlerTest::sendSpoilerTags_data()
255+
{
256+
QTest::addColumn<QString>("testInputString");
257+
QTest::addColumn<QString>("testOutputString");
258+
259+
QTest::newRow("incomplete") << u"||test"_s << u"||test"_s;
260+
QTest::newRow("complete") << u"||test||"_s << u"<span data-mx-spoiler>test</span>"_s;
261+
QTest::newRow("multiple") << u"||apple||banana||pear||"_s << u"<span data-mx-spoiler>apple</span>banana<span data-mx-spoiler>pear</span>"_s;
262+
}
263+
264+
void TextHandlerTest::sendSpoilerTags()
265+
{
266+
QFETCH(QString, testInputString);
267+
QFETCH(QString, testOutputString);
268+
269+
TextHandler testTextHandler;
270+
testTextHandler.setData(testInputString);
271+
272+
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
273+
}
274+
252275
void TextHandlerTest::receiveSpacelessSelfClosingTag()
253276
{
254277
const QString testInputString = u"Test...<br/>...ing"_s;

src/libneochat/texthandler.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ QString TextHandler::handleSendText()
5353
{
5454
m_pos = 0;
5555
m_dataBuffer = markdownToHTML(m_data);
56+
m_dataBuffer = customMarkdownToHtml(m_dataBuffer);
5657

5758
m_nextTokenType = nextTokenType(m_dataBuffer, m_pos, m_nextToken, m_nextTokenType);
5859

@@ -701,6 +702,31 @@ QString TextHandler::linkifyUrls(QString stringIn)
701702
return stringIn;
702703
}
703704

705+
QString TextHandler::customMarkdownToHtml(const QString &stringIn)
706+
{
707+
QString buffer = stringIn;
708+
709+
while (true) {
710+
const int pos = buffer.indexOf(u"||"_s);
711+
if (pos == -1) {
712+
break;
713+
}
714+
715+
int nextPos = buffer.indexOf(u"||"_s, pos + 1);
716+
if (nextPos == -1) {
717+
break;
718+
}
719+
720+
buffer.replace(pos, 2, QStringLiteral("<span data-mx-spoiler>"));
721+
722+
// we have to re-search because the index moved!
723+
nextPos = buffer.indexOf(u"||"_s, pos + 1);
724+
buffer.replace(nextPos, 2, QStringLiteral("</span>"));
725+
}
726+
727+
return buffer;
728+
}
729+
704730
QString TextHandler::editString() const
705731
{
706732
Kirigami::Platform::PlatformTheme *theme =

src/libneochat/texthandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class TextHandler : public QObject
140140
QString escapeHtml(QString stringIn);
141141
QString unescapeHtml(QString stringIn);
142142
QString linkifyUrls(QString stringIn);
143+
QString customMarkdownToHtml(const QString &stringIn);
143144

144145
QString editString() const;
145146
QString emoteString(const NeoChatRoom *room = nullptr, const Quotient::RoomEvent *event = nullptr) const;

0 commit comments

Comments
 (0)