feat: declare a Mews page's feed, keep its prolog, and lift link-only list items
All checks were successful
CI / check (push) Successful in 26s
CI / release (push) Successful in 1m1s

This commit is contained in:
randogoth 2026-10-11 16:18:05 +03:00
parent 3e659df9dd
commit c08b03db7b
9 changed files with 223 additions and 116 deletions

View file

@ -113,7 +113,7 @@ impl Writer {
// number in the text to keep the sequence readable.
if *ordered {
self.line(&format!("* {}. {text}", start + index as u64));
} else {
} else if !is_only_links_item(item) {
self.line(&format!("* {text}"));
}
for block in item {
@ -201,6 +201,16 @@ impl Writer {
}
}
/// Whether a list item holds links and nothing else worth printing, in which
/// case the `=>` lines are the whole item and a marker line above them would
/// list every entry twice -- the same reading [`is_only_links`] gives a
/// paragraph. Markup other than one paragraph keeps its marker, since the
/// shape is then doing something a link catalogue alone would not carry; so
/// does an ordered item, whose number would go with it.
fn is_only_links_item(item: &[Block]) -> bool {
matches!(item, [Block::Paragraph(inline)] if is_only_links(inline))
}
/// Whether a paragraph holds links and nothing else worth printing.
fn is_only_links(inline: &[Inline]) -> bool {
let mut saw_link = false;
@ -295,8 +305,7 @@ mod tests_support {
pub fn render(markdown: &str) -> String {
let doc = parse::markdown(markdown).unwrap();
let settings = PageSettings::default();
let ctx =
RenderCtx { url: "/x", title: "T", settings: &settings, width: None, mews_hosts: None };
let ctx = RenderCtx { url: "/x", title: "T", settings: &settings, width: None, mews: None };
let out = Gemtext.render(&doc, &ctx).unwrap();
String::from_utf8(out.body).unwrap()
}
@ -371,6 +380,19 @@ mod tests {
assert_eq!(render("- see [x](/x)\n"), "* see x\n=> /x x\n");
}
#[test]
fn a_list_of_bare_links_is_a_run_of_link_lines() {
// The shape a generator wants for a dated index: a real list, so the
// markup formats can give it <ul><li>, without gemtext printing both
// the marker line and the link line for every entry.
assert_eq!(render("- [a](/a)\n- [b](/b)\n"), "=> /a a\n=> /b b\n");
}
#[test]
fn an_ordered_list_of_bare_links_keeps_its_numbers() {
assert_eq!(render("1. [a](/a)\n"), "* 1. a\n=> /a a\n");
}
#[test]
fn code_blocks_become_fences_carrying_their_info_string() {
assert_eq!(render("```rust\nlet x = 1;\n```\n"), "```rust\nlet x = 1;\n```\n");
@ -399,8 +421,7 @@ mod tests {
// Pagination is a WML concern; a Gemini client scrolls one document.
let doc = parse::markdown("a\n\nb\n").unwrap();
let settings = PageSettings::default();
let ctx =
RenderCtx { url: "/x", title: "T", settings: &settings, width: None, mews_hosts: None };
let ctx = RenderCtx { url: "/x", title: "T", settings: &settings, width: None, mews: None };
let plain = String::from_utf8(Gemtext.render(&doc, &ctx).unwrap().body).unwrap();
assert_eq!(plain, "a\n\nb\n");
}