From f2184d0c99475f7d6ab98b2d909b2e19eb241189 Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Thu, 9 Oct 2025 13:28:41 -0500 Subject: [PATCH 1/2] fix md escaping issue with >, #, etc --- .../quarto-markdown-pandoc/src/writers/qmd.rs | 25 +++++++++++++++++-- .../qmd-json-qmd/escape_greater_than.qmd | 1 + .../qmd-json-qmd/greater_than_escape.qmd | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/escape_greater_than.qmd create mode 100644 crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/greater_than_escape.qmd diff --git a/crates/quarto-markdown-pandoc/src/writers/qmd.rs b/crates/quarto-markdown-pandoc/src/writers/qmd.rs index 95becee..4be67e0 100644 --- a/crates/quarto-markdown-pandoc/src/writers/qmd.rs +++ b/crates/quarto-markdown-pandoc/src/writers/qmd.rs @@ -694,9 +694,30 @@ fn reverse_smart_quotes(text: &str) -> String { text.replace('\u{2019}', "'") } +// Helper function to escape special markdown characters +// This follows Pandoc's escaping rules for text strings +fn escape_markdown(text: &str) -> String { + let mut result = String::new(); + for ch in text.chars() { + match ch { + // Backslash must be escaped first (conceptually) + // But since we're processing char by char, we just escape it when we see it + '\\' => result.push_str("\\\\"), + // Greater-than sign must be escaped to avoid blockquote interpretation + '>' => result.push_str("\\>"), + // Hash must be escaped to avoid header interpretation + '#' => result.push_str("\\#"), + // Other characters pass through unchanged + _ => result.push(ch), + } + } + result +} + fn write_str(s: &Str, buf: &mut dyn std::io::Write) -> std::io::Result<()> { - // FIXME what are the escaping rules that Pandoc uses? - write!(buf, "{}", reverse_smart_quotes(&s.text)) + let text = reverse_smart_quotes(&s.text); + let escaped = escape_markdown(&text); + write!(buf, "{}", escaped) } fn write_space(_: &crate::pandoc::Space, buf: &mut dyn std::io::Write) -> std::io::Result<()> { diff --git a/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/escape_greater_than.qmd b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/escape_greater_than.qmd new file mode 100644 index 0000000..a4f2aee --- /dev/null +++ b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/escape_greater_than.qmd @@ -0,0 +1 @@ +\> has to be preserved. diff --git a/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/greater_than_escape.qmd b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/greater_than_escape.qmd new file mode 100644 index 0000000..a90812d --- /dev/null +++ b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/greater_than_escape.qmd @@ -0,0 +1 @@ +> is greater than < From ec48e51d4b5edb0ffc240bc8efe89b49364b7df1 Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Thu, 9 Oct 2025 13:44:23 -0500 Subject: [PATCH 2/2] write rawinline correctly --- crates/quarto-markdown-pandoc/src/writers/qmd.rs | 4 ++-- .../tests/roundtrip_tests/qmd-json-qmd/rawhtml-inline.qmd | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/rawhtml-inline.qmd diff --git a/crates/quarto-markdown-pandoc/src/writers/qmd.rs b/crates/quarto-markdown-pandoc/src/writers/qmd.rs index 4be67e0..17b2835 100644 --- a/crates/quarto-markdown-pandoc/src/writers/qmd.rs +++ b/crates/quarto-markdown-pandoc/src/writers/qmd.rs @@ -989,8 +989,8 @@ fn write_rawinline( if raw.format == "markdown" { write!(buf, "{}", raw.text) } else { - // For other formats, use raw span notation - write!(buf, "`{}`{{{}}}", raw.text, raw.format) + // For other formats, use raw span notation with = prefix + write!(buf, "`{}`{{={}}}", raw.text, raw.format) } } fn write_note(note: &crate::pandoc::Note, buf: &mut dyn std::io::Write) -> std::io::Result<()> { diff --git a/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/rawhtml-inline.qmd b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/rawhtml-inline.qmd new file mode 100644 index 0000000..c375f25 --- /dev/null +++ b/crates/quarto-markdown-pandoc/tests/roundtrip_tests/qmd-json-qmd/rawhtml-inline.qmd @@ -0,0 +1 @@ +hello