diff --git a/crates/ruma-common/CHANGELOG.md b/crates/ruma-common/CHANGELOG.md index d4f47ec8..cf75ec83 100644 --- a/crates/ruma-common/CHANGELOG.md +++ b/crates/ruma-common/CHANGELOG.md @@ -40,6 +40,7 @@ Breaking changes: - `RedactedRoomMemberEventContent` - `RoomMessageEventContent::make_reply_to()` and `make_for_thread()` have an extra parameter to support the recommended behavior for intentional mentions in replies according to Matrix 1.7 +- In Markdown, soft line breaks are transformed into hard line breaks when compiled into HTML. Improvements: diff --git a/crates/ruma-common/src/events/room/message.rs b/crates/ruma-common/src/events/room/message.rs index 3cccb61a..bed1172e 100644 --- a/crates/ruma-common/src/events/room/message.rs +++ b/crates/ruma-common/src/events/room/message.rs @@ -942,10 +942,15 @@ pub(crate) fn parse_markdown(text: &str) -> Option { let mut found_first_paragraph = false; - let parser_events: Vec<_> = Parser::new_ext(text, OPTIONS).collect(); + let parser_events: Vec<_> = Parser::new_ext(text, OPTIONS) + .map(|event| match event { + Event::SoftBreak => Event::HardBreak, + _ => event, + }) + .collect(); let has_markdown = parser_events.iter().any(|ref event| { let is_text = matches!(event, Event::Text(_)); - let is_break = matches!(event, Event::SoftBreak | Event::HardBreak); + let is_break = matches!(event, Event::HardBreak); let is_first_paragraph_start = if matches!(event, Event::Start(Tag::Paragraph)) { if found_first_paragraph { false diff --git a/crates/ruma-common/tests/events/room_message.rs b/crates/ruma-common/tests/events/room_message.rs index 6c732ed6..8e867e91 100644 --- a/crates/ruma-common/tests/events/room_message.rs +++ b/crates/ruma-common/tests/events/room_message.rs @@ -108,42 +108,82 @@ fn text_msgtype_plain_text_serialization() { fn text_msgtype_markdown_serialization() { use ruma_common::events::room::message::TextMessageEventContent; - let formatted_message = RoomMessageEventContent::new(MessageType::Text( - TextMessageEventContent::markdown("Testing **bold** and _italic_!"), - )); + let text = "Testing **bold** and _italic_!"; + let formatted_message = + RoomMessageEventContent::new(MessageType::Text(TextMessageEventContent::markdown(text))); assert_eq!( to_json_value(&formatted_message).unwrap(), json!({ - "body": "Testing **bold** and _italic_!", + "body": text, "formatted_body": "

Testing bold and italic!

\n", "format": "org.matrix.custom.html", "msgtype": "m.text" }) ); - let plain_message_simple = RoomMessageEventContent::new(MessageType::Text( - TextMessageEventContent::markdown("Testing a simple phrase…"), - )); + let text = "Testing a simple phrase…"; + let plain_message_simple = + RoomMessageEventContent::new(MessageType::Text(TextMessageEventContent::markdown(text))); assert_eq!( to_json_value(&plain_message_simple).unwrap(), json!({ - "body": "Testing a simple phrase…", + "body": text, "msgtype": "m.text" }) ); - let plain_message_paragraphs = RoomMessageEventContent::new(MessageType::Text( - TextMessageEventContent::markdown("Testing\n\nSeveral\n\nParagraphs."), - )); + let text = "Testing\n\nSeveral\n\nParagraphs."; + let plain_message_paragraphs = + RoomMessageEventContent::new(MessageType::Text(TextMessageEventContent::markdown(text))); assert_eq!( to_json_value(&plain_message_paragraphs).unwrap(), json!({ - "body": "Testing\n\nSeveral\n\nParagraphs.", + "body": text, "formatted_body": "

Testing

\n

Several

\n

Paragraphs.

\n", "format": "org.matrix.custom.html", "msgtype": "m.text" }) ); + + let text = r#"Testing + +A paragraph +with +a soft line break + +* item 1 +* item 2 + item 2 (cont'd) +* item 3 + +``` +line 1 +line 2 +```"#; + let plain_message_paragraphs = + RoomMessageEventContent::new(MessageType::Text(TextMessageEventContent::markdown(text))); + assert_eq!( + to_json_value(&plain_message_paragraphs).unwrap(), + json!({ + "body": text, + "formatted_body": r#"

Testing

+

A paragraph
+with
+a soft line break

+ +
line 1
+line 2
+
+"#, + "format": "org.matrix.custom.html", + "msgtype": "m.text" + }) + ); } #[test]