From 5b84776c05de59ec201f9dd25bab56114fa851f0 Mon Sep 17 00:00:00 2001 From: midasmatterhorn <248507632+midasmatterhorn@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:58:35 +0300 Subject: [PATCH] formats: the Markdown code fence outgrows any backtick run in its content, so a round trip keeps it --- crates/formats/src/markdown.rs | 4 +++- crates/formats/src/tests.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/formats/src/markdown.rs b/crates/formats/src/markdown.rs index 29afb1aff..2d4782180 100644 --- a/crates/formats/src/markdown.rs +++ b/crates/formats/src/markdown.rs @@ -1294,7 +1294,9 @@ fn write_blocks(blocks: &[FBlock], out: &mut Vec) { i += 1; } let longest = lines.iter().map(|l| l.chars().filter(|c| *c == '`').count()).max().unwrap_or(0); - let fence = "`".repeat(3.max(longest + 1).min(64)); + // The fence must be longer than the longest run in the content, or a content + // line is read back as the closing fence (the `.min(64)` cap did exactly that). + let fence = "`".repeat(3.max(longest + 1)); out.push(fence.clone()); out.extend(lines); out.push(fence); diff --git a/crates/formats/src/tests.rs b/crates/formats/src/tests.rs index d22e5f695..1f680eb97 100644 --- a/crates/formats/src/tests.rs +++ b/crates/formats/src/tests.rs @@ -214,6 +214,20 @@ fn markdown_round_trip() { check_round_trip("md", true); } +/// A code line of backticks must not be mistaken for the closing fence when the file comes +/// back: the writer's fence has to be one backtick longer than any content line. +#[test] +fn markdown_code_fence_outgrows_its_content() { + let line = "`".repeat(100); + let doc = import("md", format!(" {line}\n").as_bytes()).unwrap().unwrap(); + assert_eq!(doc.plain_text(Default::default()).trim(), line); + let out = export("md", &doc).unwrap().unwrap(); + let text = String::from_utf8(out).unwrap(); + assert!(text.contains(&"`".repeat(101)), "the fence is longer than the content: {text}"); + let back = import("md", text.as_bytes()).unwrap().unwrap(); + assert_eq!(back.plain_text(Default::default()).trim(), line, "the code line survives a round trip"); +} + #[test] fn html_round_trip() { check_round_trip("html", true);