From 32e48a979ca78717a212800547c95ca0f1e67b8f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 7 Jul 2016 20:07:22 -0700 Subject: [PATCH] feat(textstyle): Change markdown syntax to be more intuitive BREAKING CHANGE: Current markdown syntax is unintuitive, and thus we have agreed on switching to @SkyzohKey's implementation. Replaces all instances of Markdown with Text Styling. Closes #3404. --- doc/user_manual_en.md | 16 +++--- src/chatlog/chatmessage.cpp | 60 +++++++++++---------- src/chatlog/chatmessage.h | 2 +- src/persistence/settings.cpp | 12 ++--- src/persistence/settings.h | 8 +-- src/widget/form/settings/generalform.cpp | 8 +-- src/widget/form/settings/generalform.h | 2 +- src/widget/form/settings/generalsettings.ui | 17 +++--- 8 files changed, 67 insertions(+), 58 deletions(-) diff --git a/doc/user_manual_en.md b/doc/user_manual_en.md index 11303ddc3..e041b4502 100644 --- a/doc/user_manual_en.md +++ b/doc/user_manual_en.md @@ -220,15 +220,15 @@ Videochats and file transfers are currently unsupported in groupchats. ## Message Styling Similar to other messaging applications, qTox supports stylized text formatting. -Formatting follows -[Markdown syntax](https://daringfireball.net/projects/markdown/syntax), thus: -* For **Bold**, surround text in double asterisks or underscores: `**text**` - or `__text__` -* For **Italics**, surround text in single asterisks or underscores: `*text*` - or `_text_` -* For **Strikethrough**, surround text in single tilde's: `~text~` -* For **Underline**, surround text in single dashes: `-text-` +* For **Bold**, surround text in single or double asterisks: `*text*` + or `**text**` +* For **Italics**, surround text in single or double forward slashes: `/text/` + or `//text//` +* For **Strikethrough**, surround text in single or double tilde's: `~text~` + or `~~text~~` +* For **Underline**, surround text in single or double underscores: `_text_` + or `__text__` * For **Code**, surround your code in in single backticks: `` `text` `` Additionally, qTox supports three modes of Markdown parsing: diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 864351a28..96be1123a 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -55,9 +55,9 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt //quotes (green text) text = detectQuotes(detectAnchors(text), type); - //markdown - if (Settings::getInstance().getMarkdownPreference() != NONE) - text = detectMarkdown(text); + //text styling + if (Settings::getInstance().getStylePreference() != NONE) + text = detectStyle(text); switch(type) { @@ -198,19 +198,21 @@ void ChatMessage::hideDate() c->hide(); } -QString ChatMessage::detectMarkdown(const QString &str) +QString ChatMessage::detectStyle(const QString &str) { QString out = str; - // Create regex for certain markdown syntax - QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** - "|(\\*)([^\\*]{2,})(\\*)" // Italics *text* - "|(\\_)([^\\_]{2,})(\\_)" // Italics _text_ - "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Bold __text__ - "|(\\-)([^\\-]{2,})(\\-)" // Underline -text- - "|(\\~)([^\\~]{2,})(\\~)" // Strike ~text~ - "|(\\~~)([^\\~\\~]{2,})(\\~~)" // Strike ~~text~~ - "|(\\`)([^\\`]{2,})(\\`)" // Codeblock `text` + // Create regex for text styling syntax + QRegExp exp("(\\*)([^\\*]{2,})(\\*)" // Bold *text* + "|(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** + "|(\\/)([^\\/]{2,})(\\/)" // Italics /text/ + "|(\\/\\/)([^\\/\\/]{2,})(\\/\\/)" // Italics //text// + "|(\\_)([^\\_]{2,})(\\_)" // Underline _text_ + "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Underline __text__ + "|(\\~)([^\\~]{2,})(\\~)" // Strike ~text~ + "|(\\~\\~)([^\\~\\~]{2,})(\\~\\~)" // Strike ~~text~~ + "|(\\`)([^\\`]{2,})(\\`)" // Codeblock `text` + "|(\\`\\`\\`)([^\\`\\`\\`]{2,})(\\`\\`\\`)" // Codeblock ```\ntext\n``` ); int offset = 0; @@ -224,28 +226,32 @@ QString ChatMessage::detectMarkdown(const QString &str) if ((snipCheck.startsWith(' ') || snipCheck.startsWith('>') || offset == 0) && ((snipCheck.endsWith(' ') || snipCheck.endsWith('<')) || offset + snippet.length() == out.length())) { - int mul = 0; // Determines how many characters to strip from markdown text - // Set mul depending on markdownPreference - if (Settings::getInstance().getMarkdownPreference() == WITHOUT_CHARS) + int mul = 0; // Determines how many characters to strip from text + // Set mul depending on styleownPreference + if (Settings::getInstance().getStylePreference() == WITHOUT_CHARS) mul = 2; - // Match captured string to corresponding md format - if (exp.cap(1) == "**") // Bold **text** + // Match captured string to corresponding style format + if (exp.cap(1) == "*" && snippet.length() > 2) // Bold *text* + htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + else if (exp.cap(4) == "**" && snippet.length() > 4) // Bold **text** htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); - else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* + else if (exp.cap(7) == "/" && snippet.length() > 2) // Italics /text/ htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); - else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ - htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); - else if (exp.cap(10) == "__"&& snippet.length() > 4) // Bold __text__ - htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); - else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text- + else if (exp.cap(10) == "//" && snippet.length() > 4) // Italics //text// + htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); + else if (exp.cap(13) == "_"&& snippet.length() > 2) // Underline _text_ htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); - else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~ + else if (exp.cap(16) == "__" && snippet.length() > 4) // Underline __text__ + htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); + else if (exp.cap(19) == "~" && snippet.length() > 2) // Strike ~text~ htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); - else if (exp.cap(19) == "~~" && snippet.length() > 4) // Strikethrough ~~text~~ + else if (exp.cap(22) == "~~" && snippet.length() > 4) // Strike ~~text~~ htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); - else if (exp.cap(22) == "`" && snippet.length() > 2) // Codeblock `text` + else if (exp.cap(25) == "`" && snippet.length() > 2) // Codeblock `text` htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + else if (exp.cap(28) == "```" && snippet.length() > 6) // Codeblock ```text``` + htmledSnippet = QString("%1").arg(snippet.mid(4*mul,snippet.length()-8*mul)); else htmledSnippet = snippet; out.replace(offset, exp.cap().length(), htmledSnippet); diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 2de1d668c..a7962cdd4 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -61,7 +61,7 @@ public: void hideDate(); protected: - static QString detectMarkdown(const QString& str); + static QString detectStyle(const QString& str); static QString detectAnchors(const QString& str); static QString detectQuotes(const QString& str, MessageType type); static QString wrapDiv(const QString& str, const QString& div); diff --git a/src/persistence/settings.cpp b/src/persistence/settings.cpp index 50429c476..a7e2049b3 100644 --- a/src/persistence/settings.cpp +++ b/src/persistence/settings.cpp @@ -182,7 +182,7 @@ void Settings::loadGlobal() separateWindow = s.value("separateWindow", false).toBool(); dontGroupWindows = s.value("dontGroupWindows", true).toBool(); groupchatPosition = s.value("groupchatPosition", true).toBool(); - markdownPreference = static_cast(s.value("markdownPreference", 1).toInt()); + stylePreference = static_cast(s.value("stylePreference", 1).toInt()); s.endGroup(); s.beginGroup("Advanced"); @@ -434,7 +434,7 @@ void Settings::saveGlobal() s.setValue("groupchatPosition", groupchatPosition); s.setValue("autoSaveEnabled", autoSaveEnabled); s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); - s.setValue("markdownPreference", static_cast(markdownPreference)); + s.setValue("stylePreference", static_cast(stylePreference)); s.endGroup(); s.beginGroup("Advanced"); @@ -1249,16 +1249,16 @@ void Settings::setDateFormat(const QString &format) dateFormat = format; } -MarkdownType Settings::getMarkdownPreference() const +StyleType Settings::getStylePreference() const { QMutexLocker locker{&bigLock}; - return markdownPreference; + return stylePreference; } -void Settings::setMarkdownPreference(MarkdownType newValue) +void Settings::setStylePreference(StyleType newValue) { QMutexLocker locker{&bigLock}; - markdownPreference = newValue; + stylePreference = newValue; } QByteArray Settings::getWindowGeometry() const diff --git a/src/persistence/settings.h b/src/persistence/settings.h index f5168bd7d..69c9abe98 100644 --- a/src/persistence/settings.h +++ b/src/persistence/settings.h @@ -36,7 +36,7 @@ namespace Db { enum class syncType; } enum ProxyType {ptNone, ptSOCKS5, ptHTTP}; -enum MarkdownType {NONE, WITH_CHARS, WITHOUT_CHARS}; +enum StyleType {NONE, WITH_CHARS, WITHOUT_CHARS}; class Settings : public QObject { @@ -212,8 +212,8 @@ public: int getThemeColor() const; void setThemeColor(const int& value); - MarkdownType getMarkdownPreference() const; - void setMarkdownPreference(MarkdownType newValue); + StyleType getStylePreference() const; + void setStylePreference(StyleType newValue); bool isCurstomEmojiFont() const; void setCurstomEmojiFont(bool value); @@ -426,7 +426,7 @@ private: // ChatView QFont chatMessageFont; - MarkdownType markdownPreference; + StyleType stylePreference; int firstColumnHandlePos; int secondColumnHandlePosFromRight; QString timestampFormat; diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index a5d2ba7fc..db512f81e 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -124,7 +124,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : const QFont chatBaseFont = s.getChatMessageFont(); bodyUI->txtChatFontSize->setValue(QFontInfo(chatBaseFont).pixelSize()); bodyUI->txtChatFont->setCurrentFont(chatBaseFont); - bodyUI->markdownComboBox->setCurrentIndex(s.getMarkdownPreference()); + bodyUI->textStyleComboBox->setCurrentIndex(s.getStylePreference()); bodyUI->cbAutorun->setChecked(s.getAutorun()); bool showSystemTray = s.getShowSystemTray(); @@ -233,7 +233,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : connect(bodyUI->showInFront, &QCheckBox::stateChanged, this, &GeneralForm::onSetShowInFront); connect(bodyUI->notifySound, &QCheckBox::stateChanged, this, &GeneralForm::onSetNotifySound); connect(bodyUI->busySound, &QCheckBox::stateChanged, this, &GeneralForm::onSetBusySound); - connect(bodyUI->markdownComboBox, &QComboBox::currentTextChanged, this, &GeneralForm::onMarkdownUpdated); + connect(bodyUI->textStyleComboBox, &QComboBox::currentTextChanged, this, &GeneralForm::onStyleUpdated); connect(bodyUI->groupAlwaysNotify, &QCheckBox::stateChanged, this, &GeneralForm::onSetGroupAlwaysNotify); connect(bodyUI->autoacceptFiles, &QCheckBox::stateChanged, this, &GeneralForm::onAutoAcceptFileChange); connect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()), this, SLOT(onAutoSaveDirChange())); @@ -396,9 +396,9 @@ void GeneralForm::onUseEmoticonsChange() bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked()); } -void GeneralForm::onMarkdownUpdated() +void GeneralForm::onStyleUpdated() { - Settings::getInstance().setMarkdownPreference(static_cast(bodyUI->markdownComboBox->currentIndex())); + Settings::getInstance().setStylePreference(static_cast(bodyUI->textStyleComboBox->currentIndex())); } void GeneralForm::onSetStatusChange() diff --git a/src/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h index d3188c6b8..6fad7acab 100644 --- a/src/widget/form/settings/generalform.h +++ b/src/widget/form/settings/generalform.h @@ -53,7 +53,7 @@ private slots: void onStyleSelected(QString style); void onTimestampSelected(int index); void onDateFormatSelected(int index); - void onMarkdownUpdated(); + void onStyleUpdated(); void onSetStatusChange(); void onAutoAwayChanged(); void onUseEmoticonsChange(); diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index 8fefc7651..710a8e614 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -39,8 +39,8 @@ 0 0 - 1270 - 1468 + 1278 + 1382 @@ -336,12 +336,12 @@ instead of closing itself. - + - New Markdown preference may not load until qTox restarts. + New text styling preference may not load until qTox restarts. - Markdown format: + Text Style format: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -375,7 +375,7 @@ instead of closing itself. - + 0 @@ -383,7 +383,10 @@ instead of closing itself. - Select Markdown preference. + Select text styling preference. + + + 1