diff --git a/main/src/ui/conversation_summary/content_item_widget_factory.vala b/main/src/ui/conversation_summary/content_item_widget_factory.vala
index 9e1edcb0..26b66664 100644
--- a/main/src/ui/conversation_summary/content_item_widget_factory.vala
+++ b/main/src/ui/conversation_summary/content_item_widget_factory.vala
@@ -60,10 +60,11 @@ public class MessageItemWidgetGenerator : WidgetGenerator, Object {
if (message_item.message.body.has_prefix("/me")) {
markup_text = markup_text.substring(3);
}
- markup_text = Markup.escape_text(markup_text);
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- markup_text = Util.make_word_bold_markup(markup_text, conversation.nickname);
+ markup_text = Util.parse_add_markup(markup_text, conversation.nickname, true, true);
+ } else {
+ markup_text = Util.parse_add_markup(markup_text, null, true, true);
}
if (message_item.message.body.has_prefix("/me")) {
@@ -73,8 +74,6 @@ public class MessageItemWidgetGenerator : WidgetGenerator, Object {
label.style_updated.connect(() => update_me_style(stream_interactor, message.real_jid ?? message.from, display_name, conversation.account, label, markup_text));
}
- markup_text = Util.make_link_markup(markup_text);
-
label.label = markup_text;
return label;
}
diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala
index 06715ad6..9472c965 100644
--- a/main/src/ui/util/helper.vala
+++ b/main/src/ui/util/helper.vala
@@ -138,39 +138,63 @@ public static bool is_24h_format() {
return settings_format == "24h" || p_format == " ";
}
-public static string make_word_bold_markup(string s, string word) {
- string ret = s;
- int elongated_by = 0;
- Regex highlight_regex = new Regex("\\b" + Regex.escape_string(word.down()) + "\\b");
- MatchInfo match_info;
- string markup_text_bak = s.down();
- highlight_regex.match(markup_text_bak, 0, out match_info);
- for (; match_info.matches(); match_info.next()) {
- int start, end;
- match_info.fetch_pos(0, out start, out end);
- ret = ret[0:start+elongated_by] + "" + ret[start+elongated_by:end+elongated_by] + "" + ret[end+elongated_by:ret.length];
- elongated_by += 7;
- }
- markup_text_bak += ""; // We need markup_text_bak to live until here because url_regex.match does not copy the string
- return ret;
-}
+public static string parse_add_markup(string s_, string? highlight_word, bool parse_links, bool parse_text_markup, bool already_escaped_ = false) {
+ string s = s_;
+ bool already_escaped = already_escaped_;
-public static string make_link_markup(string s) {
- string ret = s;
- Regex url_regex = new Regex("""(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""");
- int elongated_by = 0;
- MatchInfo match_info;
- string markup_text_bak = ret.down();
- url_regex.match(markup_text_bak, 0, out match_info);
- for (; match_info.matches(); match_info.next()) {
- int start, end;
- match_info.fetch_pos(0, out start, out end);
- string link = ret[start+elongated_by:end+elongated_by];
- ret = ret[0:start+elongated_by] + "" + link + "" + ret[end+elongated_by:ret.length];
- elongated_by += 15 + link.length;
+ if (parse_links) {
+ Regex url_regex = new Regex("""(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""");
+ MatchInfo match_info;
+ url_regex.match(s.down(), 0, out match_info);
+ if (match_info.matches()) {
+ int start, end;
+ match_info.fetch_pos(0, out start, out end);
+ string link = s[start:end];
+ return parse_add_markup(s[0:start], highlight_word, parse_links, parse_text_markup, already_escaped) +
+ "" + parse_add_markup(link, highlight_word, false, false, already_escaped) + "" +
+ parse_add_markup(s[end:s.length], highlight_word, parse_links, parse_text_markup, already_escaped);
+ }
}
- markup_text_bak += ""; // We need markup_text_bak to live until here because url_regex.match does not copy the string
- return ret;
+
+ if (!already_escaped) {
+ s = Markup.escape_text(s);
+ already_escaped = true;
+ }
+
+ if (highlight_word != null) {
+ Regex highlight_regex = new Regex("\\b" + Regex.escape_string(highlight_word.down()) + "\\b");
+ MatchInfo match_info;
+ highlight_regex.match(s.down(), 0, out match_info);
+ if (match_info.matches()) {
+ int start, end;
+ match_info.fetch_pos(0, out start, out end);
+ return parse_add_markup(s[0:start], highlight_word, parse_links, parse_text_markup, already_escaped) +
+ "" + s[start:end] + "" +
+ parse_add_markup(s[end:s.length], highlight_word, parse_links, parse_text_markup, already_escaped);
+ }
+ }
+
+ if (parse_text_markup) {
+ string[] markup_string = new string[]{"`", "_", "*"};
+ string[] convenience_tag = new string[]{"tt", "i", "b"};
+
+ for (int i = 0; i < markup_string.length; i++) {
+ Regex regex = new Regex(Regex.escape_string(markup_string[i]) + ".+" + Regex.escape_string(markup_string[i]));
+ MatchInfo match_info;
+ regex.match(s.down(), 0, out match_info);
+ if (match_info.matches()) {
+ int start, end;
+ match_info.fetch_pos(0, out start, out end);
+ start += markup_string[i].length;
+ end -= markup_string[i].length;
+ return parse_add_markup(s[0:start], highlight_word, parse_links, parse_text_markup, already_escaped) +
+ @"<$(convenience_tag[i])>" + s[start:end] + @"$(convenience_tag[i])>" +
+ parse_add_markup(s[end:s.length], highlight_word, parse_links, parse_text_markup, already_escaped);
+ }
+ }
+ }
+
+ return s;
}
}