diff --git a/Cargo.lock b/Cargo.lock index c2e8326..7895146 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -848,6 +848,15 @@ dependencies = [ "digest", ] +[[package]] +name = "html-escape" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816ea801a95538fc5f53c836697b3f8b64a9d664c4f0b91efe1fe7c92e4dbcb7" +dependencies = [ + "utf8-width", +] + [[package]] name = "http" version = "0.2.4" @@ -1487,6 +1496,7 @@ dependencies = [ "bincode", "discord_message_format", "env_logger", + "html-escape", "log", "matrix-sdk", "serde", @@ -2811,6 +2821,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b" + [[package]] name = "uuid" version = "0.8.2" diff --git a/Cargo.toml b/Cargo.toml index c4e8706..d0701be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ tokio = { version = "1.10.1", features = ["full"] } url = "2.2.2" log = "0.4.14" env_logger = "0.9.0" +html-escape = "0.2.9" [dependencies.serenity] version = "0.10.9" diff --git a/src/matrix.rs b/src/matrix.rs index db8712c..2363513 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -20,7 +20,7 @@ use tokio::sync::mpsc; use url::Url; use crate::{ - message_ast::{convert_plain, format_discord}, + message_ast::{convert_plain, format_discord, format_matrix}, messages::{MessageAuthor, MessageReference, SentMessage}, }; @@ -131,10 +131,9 @@ pub async fn forward_to_matrix( if let Some(room) = client.get_joined_room(&room_id) { let event = room .send( - AnyMessageEventContent::RoomMessage(MessageEventContent::text_plain( - format_discord( - &message.content, // TODO: Format as HTML - ), + AnyMessageEventContent::RoomMessage(MessageEventContent::text_html( + format_discord(&message.content), + format_matrix(&message.content), )), None, ) diff --git a/src/message_ast/convert_matrix.rs b/src/message_ast/convert_matrix.rs new file mode 100644 index 0000000..3bbddcb --- /dev/null +++ b/src/message_ast/convert_matrix.rs @@ -0,0 +1,51 @@ +use super::{MessageContent, Styled}; + +pub fn convert_matrix(message: &str) -> MessageContent { + todo!(); +} + +pub fn format_matrix(message_content: &MessageContent) -> String { + message_content + .iter() + .map(|component| match component { + Styled::Plain(text) => html_escape::encode_text(text).to_string(), + Styled::Link { target, text } => format!( + r#"{}"#, + html_escape::encode_quoted_attribute(target), + format_matrix(text) + ), + + Styled::Italic(inner) => format!("{}", format_matrix(inner)), + Styled::Bold(inner) => format!("{}", format_matrix(inner)), + Styled::Strikethrough(inner) => format!("{}", format_matrix(inner)), + Styled::Underline(inner) => format!("{}", format_matrix(inner)), + + Styled::Code(code) => format!("{}", html_escape::encode_text(code)), + Styled::CodeBlock { lang, source } => { + format!( + r#"
{}
"#, + lang.as_ref() + .map(|lang| format!( + r#" class="language-{}""#, + html_escape::encode_quoted_attribute(lang) + )) + .unwrap_or("".to_string()), + source, + ) + } + + Styled::Spoiler { reason, content } => format!( + "{}", + reason + .as_ref() + .map(|reason| format!(r#"="{}""#, html_escape::encode_quoted_attribute(reason))) + .unwrap_or("".to_string()), + format_matrix(content) + ), + Styled::HardBreak => "
".to_string(), + Styled::BlockQuote(inner) => { + format!("
{}
", format_matrix(inner)) + } + }) + .collect() +} diff --git a/src/message_ast/mod.rs b/src/message_ast/mod.rs index 7131671..7ae9660 100644 --- a/src/message_ast/mod.rs +++ b/src/message_ast/mod.rs @@ -1,4 +1,5 @@ mod convert_discord; +mod convert_matrix; mod convert_plain; pub type MessageContent = Vec; @@ -31,4 +32,5 @@ pub enum Styled { } pub use convert_discord::{convert_discord, format_discord}; +pub use convert_matrix::{convert_matrix, format_matrix}; pub use convert_plain::convert_plain;