Support displaying shortcodes instead of Emojis in messages (#222)

This commit is contained in:
Bernhard Bliem 2024-03-24 00:35:10 +01:00 committed by GitHub
parent 0c52375e06
commit 23a729e565
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 164 additions and 49 deletions

View file

@ -148,7 +148,7 @@ impl Table {
}
}
fn to_text(&self, width: usize, style: Style) -> Text {
fn to_text(&self, width: usize, style: Style, emoji_shortcodes: bool) -> Text {
let mut text = Text::default();
let columns = self.columns();
let cell_total = width.saturating_sub(columns).saturating_sub(1);
@ -166,7 +166,8 @@ impl Table {
if let Some(caption) = &self.caption {
let subw = width.saturating_sub(6);
let mut printer = TextPrinter::new(subw, style, true).align(Alignment::Center);
let mut printer =
TextPrinter::new(subw, style, true, emoji_shortcodes).align(Alignment::Center);
caption.print(&mut printer, style);
for mut line in printer.finish().lines {
@ -213,7 +214,7 @@ impl Table {
CellType::Data => style,
};
cell.to_text(*w, style)
cell.to_text(*w, style, emoji_shortcodes)
} else {
space_text(*w, style)
};
@ -274,8 +275,8 @@ pub enum StyleTreeNode {
}
impl StyleTreeNode {
pub fn to_text(&self, width: usize, style: Style) -> Text {
let mut printer = TextPrinter::new(width, style, true);
pub fn to_text(&self, width: usize, style: Style, emoji_shortcodes: bool) -> Text {
let mut printer = TextPrinter::new(width, style, true, emoji_shortcodes);
self.print(&mut printer, style);
printer.finish()
}
@ -428,7 +429,7 @@ impl StyleTreeNode {
}
},
StyleTreeNode::Table(table) => {
let text = table.to_text(width, style);
let text = table.to_text(width, style, printer.emoji_shortcodes());
printer.push_text(text);
},
StyleTreeNode::Break => {
@ -464,8 +465,14 @@ impl StyleTree {
return links;
}
pub fn to_text(&self, width: usize, style: Style, hide_reply: bool) -> Text<'_> {
let mut printer = TextPrinter::new(width, style, hide_reply);
pub fn to_text(
&self,
width: usize,
style: Style,
hide_reply: bool,
emoji_shortcodes: bool,
) -> Text<'_> {
let mut printer = TextPrinter::new(width, style, hide_reply, emoji_shortcodes);
for child in self.children.iter() {
child.print(&mut printer, style);
@ -805,6 +812,7 @@ pub mod tests {
use super::*;
use crate::util::space_span;
use pretty_assertions::assert_eq;
use unicode_width::UnicodeWidthStr;
#[test]
fn test_header() {
@ -812,7 +820,7 @@ pub mod tests {
let s = "<h1>Header 1</h1>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled(" ", bold),
@ -824,7 +832,7 @@ pub mod tests {
let s = "<h2>Header 2</h2>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled("#", bold),
@ -837,7 +845,7 @@ pub mod tests {
let s = "<h3>Header 3</h3>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled("#", bold),
@ -851,7 +859,7 @@ pub mod tests {
let s = "<h4>Header 4</h4>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled("#", bold),
@ -866,7 +874,7 @@ pub mod tests {
let s = "<h5>Header 5</h5>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled("#", bold),
@ -882,7 +890,7 @@ pub mod tests {
let s = "<h6>Header 6</h6>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("#", bold),
Span::styled("#", bold),
@ -909,7 +917,7 @@ pub mod tests {
let s = "<b>Bold!</b>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Bold", bold),
Span::styled("!", bold),
@ -918,7 +926,7 @@ pub mod tests {
let s = "<strong>Bold!</strong>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Bold", bold),
Span::styled("!", bold),
@ -927,7 +935,7 @@ pub mod tests {
let s = "<i>Italic!</i>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Italic", italic),
Span::styled("!", italic),
@ -936,7 +944,7 @@ pub mod tests {
let s = "<em>Italic!</em>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Italic", italic),
Span::styled("!", italic),
@ -945,7 +953,7 @@ pub mod tests {
let s = "<del>Strikethrough!</del>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Strikethrough", strike),
Span::styled("!", strike),
@ -954,7 +962,7 @@ pub mod tests {
let s = "<strike>Strikethrough!</strike>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Strikethrough", strike),
Span::styled("!", strike),
@ -963,7 +971,7 @@ pub mod tests {
let s = "<u>Underline!</u>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Underline", underl),
Span::styled("!", underl),
@ -972,7 +980,7 @@ pub mod tests {
let s = "<font color=\"#ff0000\">Red!</u>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Red", red),
Span::styled("!", red),
@ -981,7 +989,7 @@ pub mod tests {
let s = "<font color=\"red\">Red!</u>";
let tree = parse_matrix_html(s);
let text = tree.to_text(20, Style::default(), false);
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::styled("Red", red),
Span::styled("!", red),
@ -993,7 +1001,7 @@ pub mod tests {
fn test_paragraph() {
let s = "<p>Hello world!</p><p>Content</p><p>Goodbye world!</p>";
let tree = parse_matrix_html(s);
let text = tree.to_text(10, Style::default(), false);
let text = tree.to_text(10, Style::default(), false, false);
assert_eq!(text.lines.len(), 7);
assert_eq!(
text.lines[0],
@ -1020,7 +1028,7 @@ pub mod tests {
fn test_blockquote() {
let s = "<blockquote>Hello world!</blockquote>";
let tree = parse_matrix_html(s);
let text = tree.to_text(10, Style::default(), false);
let text = tree.to_text(10, Style::default(), false, false);
assert_eq!(text.lines.len(), 2);
assert_eq!(
text.lines[0],
@ -1036,7 +1044,7 @@ pub mod tests {
fn test_list_unordered() {
let s = "<ul><li>List Item 1</li><li>List Item 2</li><li>List Item 3</li></ul>";
let tree = parse_matrix_html(s);
let text = tree.to_text(8, Style::default(), false);
let text = tree.to_text(8, Style::default(), false, false);
assert_eq!(text.lines.len(), 6);
assert_eq!(
text.lines[0],
@ -1098,7 +1106,7 @@ pub mod tests {
fn test_list_ordered() {
let s = "<ol><li>List Item 1</li><li>List Item 2</li><li>List Item 3</li></ol>";
let tree = parse_matrix_html(s);
let text = tree.to_text(9, Style::default(), false);
let text = tree.to_text(9, Style::default(), false, false);
assert_eq!(text.lines.len(), 6);
assert_eq!(
text.lines[0],
@ -1168,7 +1176,7 @@ pub mod tests {
<tr><td>a</td><td>b</td><td>c</td></tr>\
</tbody></table>";
let tree = parse_matrix_html(s);
let text = tree.to_text(15, Style::default(), false);
let text = tree.to_text(15, Style::default(), false, false);
let bold = Style::default().add_modifier(StyleModifier::BOLD);
assert_eq!(text.lines.len(), 11);
@ -1261,7 +1269,7 @@ pub mod tests {
let s = "<mx-reply>This was replied to</mx-reply>This is the reply";
let tree = parse_matrix_html(s);
let text = tree.to_text(10, Style::default(), false);
let text = tree.to_text(10, Style::default(), false, false);
assert_eq!(text.lines.len(), 4);
assert_eq!(
text.lines[0],
@ -1298,7 +1306,7 @@ pub mod tests {
);
let tree = parse_matrix_html(s);
let text = tree.to_text(10, Style::default(), true);
let text = tree.to_text(10, Style::default(), true, false);
assert_eq!(text.lines.len(), 2);
assert_eq!(
text.lines[0],
@ -1325,7 +1333,7 @@ pub mod tests {
fn test_self_closing() {
let s = "Hello<br>World<br>Goodbye";
let tree = parse_matrix_html(s);
let text = tree.to_text(7, Style::default(), true);
let text = tree.to_text(7, Style::default(), true, false);
assert_eq!(text.lines.len(), 3);
assert_eq!(text.lines[0], Line::from(vec![Span::raw("Hello"), Span::raw(" "),]));
assert_eq!(text.lines[1], Line::from(vec![Span::raw("World"), Span::raw(" "),]));
@ -1336,7 +1344,7 @@ pub mod tests {
fn test_embedded_newline() {
let s = "<p>Hello\nWorld</p>";
let tree = parse_matrix_html(s);
let text = tree.to_text(15, Style::default(), true);
let text = tree.to_text(15, Style::default(), true, false);
assert_eq!(text.lines.len(), 1);
assert_eq!(
text.lines[0],
@ -1359,7 +1367,7 @@ pub mod tests {
"</code></pre>\n"
);
let tree = parse_matrix_html(s);
let text = tree.to_text(25, Style::default(), true);
let text = tree.to_text(25, Style::default(), true, false);
assert_eq!(text.lines.len(), 5);
assert_eq!(
text.lines[0],
@ -1420,4 +1428,28 @@ pub mod tests {
])
);
}
#[test]
fn test_emoji_shortcodes() {
for shortcode in ["exploding_head", "polar_bear", "canada"] {
let emoji = emojis::get_by_shortcode(shortcode).unwrap().as_str();
let emoji_width = UnicodeWidthStr::width(emoji);
let replacement = format!(":{shortcode}:");
let replacement_width = UnicodeWidthStr::width(replacement.as_str());
let s = format!("<p>{emoji}</p>");
let tree = parse_matrix_html(s.as_str());
// Test with emojis_shortcodes set to false
let text = tree.to_text(20, Style::default(), false, false);
assert_eq!(text.lines, vec![Line::from(vec![
Span::raw(emoji),
space_span(20 - emoji_width, Style::default()),
]),]);
// Test with emojis_shortcodes set to true
let text = tree.to_text(20, Style::default(), false, true);
assert_eq!(text.lines, vec![Line::from(vec![
Span::raw(replacement.as_str()),
space_span(20 - replacement_width, Style::default()),
])]);
}
}
}