From 9e8f0b7409ff34b1235908b4c9d619b2a43d7a11 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Fri, 7 Sep 2018 20:05:30 +0300 Subject: [PATCH] Initial support for sending markdown formatted messages fixes #283 --- CMakeLists.txt | 1 + deps/CMakeLists.txt | 11 +++++++++++ deps/cmake/Maddy.cmake | 20 ++++++++++++++++++++ src/Utils.cpp | 23 +++++++++++++++++++++++ src/Utils.h | 11 +++++++++++ src/timeline/TimelineItem.cpp | 10 +++++----- src/timeline/TimelineView.cpp | 15 +++++++++++++-- 7 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 deps/cmake/Maddy.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 42990445..703a6156 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -250,6 +250,7 @@ find_package(OpenSSL REQUIRED) find_package(MatrixClient 0.1.0 REQUIRED) find_package(Olm 2 REQUIRED) find_package(spdlog 1.0.0 CONFIG REQUIRED) +find_package(maddy 1.0.0 CONFIG REQUIRED) if(NOT LMDBXX_INCLUDE_DIR) find_path(LMDBXX_INCLUDE_DIR diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index c94efcd7..1d131f6a 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -26,6 +26,7 @@ option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${USE_BUNDLED}) option(USE_BUNDLED_OLM "Use the bundled version of libolm." ${USE_BUNDLED}) option(USE_BUNDLED_TWEENY "Use the bundled version of Tweeny." ${USE_BUNDLED}) option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdbxx." ${USE_BUNDLED}) +option(USE_BUNDLED_MADDY "Use the bundled version of maddy." ${USE_BUNDLED}) option(USE_BUNDLED_MATRIX_CLIENT "Use the bundled version of mtxclient." ${USE_BUNDLED}) @@ -64,6 +65,12 @@ set(SPDLOG_URL https://github.com/gabime/spdlog/archive/v1.1.0.tar.gz) set(SPDLOG_HASH 3dbcbfd8c07e25f5e0d662b194d3a7772ef214358c49ada23c044c4747ce8b19) +set( + MADDY_URL + https://github.com/mujx/maddy/archive/d6b32013a580d40de57ac8b6650846abecbb071f.tar.gz + ) +set(MADDY_HASH c40df975420aa9f1549d9e528af84243f701b5264ed9c32d86b1cfc9306c15b8) + set(JSON_HEADER_URL https://github.com/nlohmann/json/releases/download/v3.2.0/json.hpp) set(JSON_HEADER_HASH @@ -80,6 +87,10 @@ if(USE_BUNDLED_SPDLOG) include(SpdLog) endif() +if(USE_BUNDLED_MADDY) + include(Maddy) +endif() + if(USE_BUNDLED_OLM) include(Olm) endif() diff --git a/deps/cmake/Maddy.cmake b/deps/cmake/Maddy.cmake new file mode 100644 index 00000000..699d214d --- /dev/null +++ b/deps/cmake/Maddy.cmake @@ -0,0 +1,20 @@ +set(WINDOWS_FLAGS "") + +if(MSVC) + set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") +endif() + +ExternalProject_Add( + Maddy + + URL ${MADDY_URL} + URL_HASH SHA256=${MADDY_HASH} + + BUILD_IN_SOURCE 1 + SOURCE_DIR ${DEPS_BUILD_DIR}/maddy + CONFIGURE_COMMAND ${CMAKE_COMMAND} + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} + ${DEPS_BUILD_DIR}/maddy + ${WINDOWS_FLAGS}) + +list(APPEND THIRD_PARTY_DEPS Maddy) diff --git a/src/Utils.cpp b/src/Utils.cpp index 40039179..5d5508b6 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -3,10 +3,12 @@ #include #include #include +#include #include #include #include +#include #include "Config.h" @@ -327,3 +329,24 @@ utils::linkifyMessage(const QString &body) return textString; } + +std::string +utils::markdownToHtml(const std::string &text) +{ + std::stringstream markdownInput(text); + auto parser = std::make_shared(); + + return parser->Parse(markdownInput); +} + +std::string +utils::markdownToHtml(const QString &text) +{ + return markdownToHtml(text.toStdString()); +} + +std::string +utils::stripHtml(const std::string &text) +{ + return QString::fromStdString(text).remove(QRegExp("<[^>]*>")).toStdString(); +} diff --git a/src/Utils.h b/src/Utils.h index 62af310b..2ac6d41b 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -215,4 +215,15 @@ getMessageBody(const RoomMessageT &event) //! Replace raw URLs in text with HTML link tags. QString linkifyMessage(const QString &body); + +//! Convert the input markdown text to html. +std::string +markdownToHtml(const QString &text); + +std::string +markdownToHtml(const std::string &text); + +//! Return the plain text version of an html document. +std::string +stripHtml(const std::string &text); } diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index 267dea15..8e0401a8 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -265,16 +265,16 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty, auto timestamp = QDateTime::currentDateTime(); if (ty == mtx::events::MessageType::Emote) { - body = QString("* %1 %2").arg(displayName).arg(body); + body = QString("%1 %2").arg(displayName).arg(body); descriptionMsg_ = {"", userid, body, utils::descriptiveTime(timestamp), timestamp}; } else { descriptionMsg_ = { "You: ", userid, body, utils::descriptiveTime(timestamp), timestamp}; } - body = body.toHtmlEscaped(); - body.replace(conf::strings::url_regex, conf::strings::url_html); - body.replace("\n", "
"); + body = QString::fromStdString(utils::markdownToHtml(body)); + body = utils::linkifyMessage(body); + generateTimestamp(timestamp); if (withSender) { @@ -489,7 +489,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts); auto displayName = Cache::displayName(room_id_, sender); - auto emoteMsg = QString("* %1 %2").arg(displayName).arg(formatted_body); + auto emoteMsg = QString("%1 %2").arg(displayName).arg(formatted_body); descriptionMsg_ = {"", sender, emoteMsg, utils::descriptiveTime(timestamp), timestamp}; diff --git a/src/timeline/TimelineView.cpp b/src/timeline/TimelineView.cpp index bf828a8e..d09f5d5f 100644 --- a/src/timeline/TimelineView.cpp +++ b/src/timeline/TimelineView.cpp @@ -1233,8 +1233,12 @@ template<> mtx::events::msg::Emote toRoomMessage(const PendingMessage &m) { + auto html = utils::markdownToHtml(m.body); + mtx::events::msg::Emote emote; - emote.body = m.body.toStdString(); + emote.body = utils::stripHtml(html); + emote.formatted_body = html; + return emote; } @@ -1254,8 +1258,15 @@ template<> mtx::events::msg::Text toRoomMessage(const PendingMessage &m) { + auto html = utils::markdownToHtml(m.body); + mtx::events::msg::Text text; - text.body = m.body.toStdString(); + text.body = utils::stripHtml(html); + text.formatted_body = html; + + std::cout << "body: " << text.body << std::endl; + std::cout << "formatted_body: " << text.formatted_body << std::endl; + return text; }