fix: a hard break between links is still only links

The gemtext renderer prints a bare => line for a paragraph holding nothing but
links, which is what lets a generator emit a navigable menu. is_only_links
tolerated soft breaks but not hard ones, so a generator had to choose: soft
breaks and a clean gemtext menu, or hard breaks and a menu that does not run
together on the formats that lay a paragraph out inline.

That was a false choice. A hard break between links is still a run of nothing
but links, and the inline formats already turn it into <br/>. Without this,
asking for the break made gemtext read the paragraph as prose and print its
flattened text alongside the => lines, listing every entry twice.

Found serving a real capsule: six area links rendered as one run-on line in a
browser and on a handset while gemtext looked perfect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
randogoth 2026-10-06 09:41:26 +03:00
parent dffa42c304
commit 088e860cad

View file

@ -205,7 +205,13 @@ fn is_only_links(inline: &[Inline]) -> bool {
match item { match item {
Inline::Link { .. } | Inline::Image { .. } => saw_link = true, Inline::Link { .. } | Inline::Image { .. } => saw_link = true,
Inline::Text(text) if text.trim().is_empty() => {} Inline::Text(text) if text.trim().is_empty() => {}
Inline::SoftBreak => {} // Either break kind. A hard break between links is still a run of
// nothing but links, and a generator has good reason to use one:
// the formats that lay links out inline need <br/> to stop a menu
// running together on one line, and refusing it here would make
// the paragraph print its flattened text as well as the => lines,
// listing every entry twice.
Inline::SoftBreak | Inline::HardBreak => {}
_ => return false, _ => return false,
} }
} }
@ -300,6 +306,16 @@ mod tests {
use super::tests_support::render; use super::tests_support::render;
use super::*; use super::*;
#[test]
fn a_hard_break_between_links_still_lifts_them() {
// Generators emit hard breaks so the inline formats put each link on
// its own line. gemtext must not read that as prose and print the
// flattened text alongside the => lines, which would list every entry
// twice.
let out = render("[one](/a) \n[two](/b)\n");
assert_eq!(out, "=> /a one\n=> /b two\n");
}
#[test] #[test]
fn headings_flatten_onto_three_levels() { fn headings_flatten_onto_three_levels() {
assert_eq!(render("# a\n## b\n### c\n#### d\n"), "# a\n\n## b\n\n### c\n\n### d\n"); assert_eq!(render("# a\n## b\n### c\n#### d\n"), "# a\n\n## b\n\n### c\n\n### d\n");