diff --git a/espanso-engine/src/process/middleware/markdown.rs b/espanso-engine/src/process/middleware/markdown.rs index 7deec85..ff1bea2 100644 --- a/espanso-engine/src/process/middleware/markdown.rs +++ b/espanso-engine/src/process/middleware/markdown.rs @@ -45,15 +45,8 @@ impl Middleware for MarkdownMiddleware { // See also: https://github.com/federico-terzi/espanso/issues/759 let html = std::panic::catch_unwind(|| markdown::to_html(&m_event.markdown)); if let Ok(html) = html { - let mut html = html.trim(); - - // Remove the surrounding paragraph - if html.starts_with("
") { - html = html.trim_start_matches("
"); - } - if html.ends_with("
") { - html = html.trim_end_matches(""); - } + let html = html.trim(); + let html = remove_paragraph_tag_if_single_occurrence(html); return Event::caused_by( event.source_id, @@ -72,4 +65,42 @@ impl Middleware for MarkdownMiddleware { } } -// TODO: test +// If the match is composed of a single paragraph, we remove the tag to avoid +// a forced "newline" on some editors. In other words, we assume that if the snippet +// is composed of a single paragraph, then it should be inlined. +// On the other hand, if the snippet is composed of multiple paragraphs, then we +// avoid removing the paragraph to prevent HTML corruption. +// See: https://github.com/federico-terzi/espanso/issues/811 +fn remove_paragraph_tag_if_single_occurrence(html: &str) -> &str { + let paragraph_count = html.matches("").count(); + if paragraph_count <= 1 { + let mut new_html = html; + if new_html.starts_with("
") { + new_html = new_html.trim_start_matches("
"); + } + if new_html.ends_with("
") { + new_html = new_html.trim_end_matches(""); + } + + new_html + } else { + html + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_remove_paragraph_tag_if_single_occurrence() { + assert_eq!( + remove_paragraph_tag_if_single_occurrence("single occurrence
"), + "single occurrence" + ); + assert_eq!( + remove_paragraph_tag_if_single_occurrence("multi
occurrence
"), + "multi
occurrence
" + ); + } +}