Display bold/italic/monospace message formating, improve message-to-markup parsing
fixes #433 fixes #442
This commit is contained in:
parent
6b7ef800f5
commit
006e25aab8
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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] + "<b>" + ret[start+elongated_by:end+elongated_by] + "</b>" + 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;
|
||||
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`!()\[\]{};:'".,<>?«»“”‘’]))""");
|
||||
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()) {
|
||||
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 = ret[start+elongated_by:end+elongated_by];
|
||||
ret = ret[0:start+elongated_by] + "<a href=\"" + link + "\">" + link + "</a>" + ret[end+elongated_by:ret.length];
|
||||
elongated_by += 15 + link.length;
|
||||
string link = s[start:end];
|
||||
return parse_add_markup(s[0:start], highlight_word, parse_links, parse_text_markup, already_escaped) +
|
||||
"<a href=\"" + Markup.escape_text(link) + "\">" + parse_add_markup(link, highlight_word, false, false, already_escaped) + "</a>" +
|
||||
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) +
|
||||
"<b>" + s[start:end] + "</b>" +
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue