Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
[Rust] fix multiple lines in markdown mode (#907)
Browse files Browse the repository at this point in the history
  • Loading branch information
Velin92 authored Dec 14, 2023
1 parent efe567d commit d43db0a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
34 changes: 21 additions & 13 deletions crates/wysiwyg/src/dom/parser/markdown/markdown_html_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use md_parser::Event;
use pulldown_cmark as md_parser;

use crate::{dom::MarkdownParseError, UnicodeString};
Expand All @@ -29,29 +30,37 @@ impl MarkdownHTMLParser {
options.insert(Options::ENABLE_STRIKETHROUGH);

let markdown = markdown.to_string();

let parser = Parser::new_ext(&markdown, options);
let parser_events: Vec<_> = Parser::new_ext(&markdown, options)
.map(|event| match event {
// this allows for line breaks to be parsed correctly from markdown
Event::SoftBreak => Event::HardBreak,
_ => event,
})
.collect();

let mut html = String::new();

compile_to_html(&mut html, parser);
compile_to_html(&mut html, parser_events.into_iter());

// By default, there is a `<p>…</p>\n` around the HTML content. That's the
// correct way to handle a text block in Markdown. But it breaks our
// assumption regarding the HTML markup. So let's remove it.
let html = {
if !html.starts_with("<p>") {
&html[..]
} else {
// only remove the external <p> if there is only one
if html.starts_with("<p>") && html.matches("<p>").count() == 1 {
let p = "<p>".len();
let ppnl = "</p>\n".len();

&html[p..html.len() - ppnl]
html[p..html.len() - ppnl].to_string()
} else {
html[..].to_string()
}
};

// Remove any trailing newline characters from block tags
let html = html
// Allow for having a newline between paragraphs
.replace("</p>\n<p>", "</p><p>&nbsp;</p><p>")
// Remove any trailing newline characters from block tags
.replace("<ul>\n", "<ul>")
.replace("</ul>\n", "</ul>")
.replace("<ol>\n", "<ol>")
Expand All @@ -63,11 +72,10 @@ impl MarkdownHTMLParser {
.replace("<pre>\n", "<pre>")
.replace("</pre>\n", "</pre>")
.replace("<p>\n", "<p>")
.replace("</p>\n", "</p>");

// Remove the newline from the end of the single code tag that wraps the content
// of a formatted codeblock
let html = html.replace("\n</code>", "</code>");
.replace("</p>\n", "</p>")
// Remove the newline from the end of the single code tag that wraps the content
// of a formatted codeblock
.replace("\n</code>", "</code>");

Ok(S::try_from(html).unwrap())
}
Expand Down
43 changes: 43 additions & 0 deletions crates/wysiwyg/src/tests/test_set_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,22 @@ fn set_content_from_html_moves_cursor_to_the_end() {
assert_eq!(tx(&model), "content|");
}

#[test]
fn set_content_from_html_single_br() {
let mut model = cm("|");
model.set_content_from_html(&utf16("test<br>test")).unwrap();
assert_eq!(tx(&model), "<p>test</p><p>test|</p>");
}

#[test]
fn set_content_from_html_multiple_br() {
let mut model = cm("|");
model
.set_content_from_html(&utf16("test<br><br>test"))
.unwrap();
assert_eq!(tx(&model), "<p>test</p><p>&nbsp;</p><p>test|</p>");
}

#[test]
fn clear() {
let mut model = cm("|");
Expand Down Expand Up @@ -194,3 +210,30 @@ fn set_content_from_markdown_codeblock_with_newlines() {
.unwrap();
assert_eq!(tx(&model), "<pre><code>I am a code block|</code></pre>");
}

#[test]
fn set_content_from_markdown_codeblock_with_newlines_in_the_middle() {
let mut model = cm("|");
model
.set_content_from_markdown(&utf16("```\nI am\na code block\n```"))
.unwrap();
assert_eq!(tx(&model), "<pre><code>I am\na code block|</code></pre>");
}

#[test]
fn set_content_from_markdown_multiple_new_lines() {
let mut model = cm("|");
model
.set_content_from_markdown(&utf16("test\n\n\ntest"))
.unwrap();
assert_eq!(tx(&model), "<p>test</p><p>&nbsp;</p><p>test|</p>");
}

#[test]
fn set_content_from_markdown_one_new_line() {
let mut model = cm("|");
model
.set_content_from_markdown(&utf16("test\ntest"))
.unwrap();
assert_eq!(tx(&model), "<p>test</p><p>test|</p>");
}

0 comments on commit d43db0a

Please sign in to comment.