diff --git a/src/message_ast/convert_matrix.rs b/src/message_ast/convert_matrix.rs index 2fff3fd..2b29ac3 100644 --- a/src/message_ast/convert_matrix.rs +++ b/src/message_ast/convert_matrix.rs @@ -12,6 +12,7 @@ pub fn convert_matrix(message: &str) -> MessageContent { let mut parents = vec![]; let mut components = vec![]; + let mut skip_text = false; for edge in dom.traverse() { match edge { @@ -39,6 +40,10 @@ pub fn convert_matrix(message: &str) -> MessageContent { } } + local_name!("code") => { + skip_text = true; + } + _ => {} } } @@ -47,7 +52,9 @@ pub fn convert_matrix(message: &str) -> MessageContent { NodeEdge::End(node) => match node.data() { NodeData::Text(text) => { - components.push(MessageComponent::Plain(text.borrow().clone())); + if !skip_text { + components.push(MessageComponent::Plain(text.borrow().clone())); + } } NodeData::Element(element) => { macro_rules! construct_component { @@ -105,6 +112,37 @@ pub fn convert_matrix(message: &str) -> MessageContent { }) } } + local_name!("code") => { + // is_code_block = whether we are the child of a
tag + let is_code_block = node + .parent() + .as_ref() + .map(|p| p.data()) + .and_then(|d| match d { + NodeData::Element(e) => { + Some(e.name.local == local_name!("pre")) + } + _ => None, + }) + .unwrap_or(false); + + components.push(if is_code_block { + let attrs = element.attributes.borrow(); + let lang = attrs + .get(local_name!("class")) + .and_then(|lang| lang.strip_prefix("language-")) + .map(|s| s.to_string()); + + MessageComponent::CodeBlock { + lang, + source: node.text_contents(), + } + } else { + MessageComponent::Code(node.text_contents()) + }); + + skip_text = false; + } _ => {} } } @@ -168,7 +206,7 @@ pub fn format_matrix(message_content: &[MessageComponent]) -> String { } #[test] -fn simple_matrix_parsing() { +fn simple_parsing() { use MessageComponent::*; let html = @@ -208,3 +246,28 @@ fn spoiler_parsing() { }] ); } + +#[test] +fn code_parsing() { + use MessageComponent::*; + + let html = r#"hello_world();
"#; + + assert_eq!( + convert_matrix(html), + vec![Code("hello_world();".to_string())] + ); + + let html = r#""#; + + assert_eq!( + convert_matrix(html), + vec![CodeBlock { + lang: Some("javascript".to_string()), + source: "console.log(\"hello, world!\");\nconsole.table({ a: 1, b: 2, c: 3 });\n" + .to_string(), + }] + ); +}console.log("hello, world!"); +console.table({ a: 1, b: 2, c: 3 }); +