events: Transform Markdown soft line breaks into hard line breaks
This patch transforms Markdown soft line breaks into hard line breaks when rendering to HTML. The [CommonMark specification about soft line breaks](https://spec.commonmark.org/0.30/#soft-line-breaks) specifies: > A renderer may also provide an option to render soft line breaks as > hard line breaks. Refering to https://github.com/vector-im/element-x-ios/issues/1418, some people are expecting to get soft line breaks rendered at hard ones. This patch updates the Markdown test to include this conversion of soft to hard line breaks. It includes a list and a code block, to ensure not _all_ soft breaks are transformed into hard breaks; only the ones we expect.
This commit is contained in:
parent
73b6113819
commit
ea41901211
@ -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:
|
||||
|
||||
|
@ -942,10 +942,15 @@ pub(crate) fn parse_markdown(text: &str) -> Option<String> {
|
||||
|
||||
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
|
||||
|
@ -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": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\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": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\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#"<p>Testing</p>
|
||||
<p>A paragraph<br />
|
||||
with<br />
|
||||
a soft line break</p>
|
||||
<ul>
|
||||
<li>item 1</li>
|
||||
<li>item 2<br />
|
||||
item 2 (cont'd)</li>
|
||||
<li>item 3</li>
|
||||
</ul>
|
||||
<pre><code>line 1
|
||||
line 2
|
||||
</code></pre>
|
||||
"#,
|
||||
"format": "org.matrix.custom.html",
|
||||
"msgtype": "m.text"
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user