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
https://github.com/commonmark/cmark/pull/123) so we have to implement
our own parsing function. New tests are also added for this too.
This commit is contained in:
Joshua Goins
2025-04-27 17:04:05 -04:00
parent 86a43c4f7e
commit 6b5996a1bd
3 changed files with 50 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ QString TextHandler::handleSendText()
{
m_pos = 0;
m_dataBuffer = markdownToHTML(m_data);
m_dataBuffer = customMarkdownToHtml(m_dataBuffer);
m_nextTokenType = nextTokenType(m_dataBuffer, m_pos, m_nextToken, m_nextTokenType);
@@ -701,6 +702,31 @@ QString TextHandler::linkifyUrls(QString stringIn)
return stringIn;
}
QString TextHandler::customMarkdownToHtml(const QString &stringIn)
{
QString buffer = stringIn;
while (true) {
const int pos = buffer.indexOf(u"||"_s);
if (pos == -1) {
break;
}
int nextPos = buffer.indexOf(u"||"_s, pos + 1);
if (nextPos == -1) {
break;
}
buffer.replace(pos, 2, QStringLiteral("<span data-mx-spoiler>"));
// we have to re-search because the index moved!
nextPos = buffer.indexOf(u"||"_s, pos + 1);
buffer.replace(nextPos, 2, QStringLiteral("</span>"));
}
return buffer;
}
QString TextHandler::editString() const
{
Kirigami::Platform::PlatformTheme *theme =

View File

@@ -140,6 +140,7 @@ private:
QString escapeHtml(QString stringIn);
QString unescapeHtml(QString stringIn);
QString linkifyUrls(QString stringIn);
QString customMarkdownToHtml(const QString &stringIn);
QString editString() const;
QString emoteString(const NeoChatRoom *room = nullptr, const Quotient::RoomEvent *event = nullptr) const;