Merge PR #1788: formats: the Markdown code fence outgrows any backtick run in its content, so a round trip keeps it

This commit is contained in:
aiongg
2026-10-22 01:19:43 +00:00
2 changed files with 17 additions and 1 deletions
+3 -1
View File
@@ -1335,7 +1335,9 @@ fn write_blocks(blocks: &[FBlock], out: &mut Vec<String>) {
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);
+14
View File
@@ -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);