Name the author ahead of the feed on issue index lines

Every list of articles now reads "Author · Feed · Publication · N min":
the signed-in issue page, the public issue page, the RSS feed and the
EPUB's In This Issue page. `author_label` drops an author that is empty
or only repeats the feed's title, as a dozen personal blogs do. Article
pages keep their own byline.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VXYGBPoHZSDSfE5WcJ9bvj
This commit is contained in:
2026-09-09 18:12:34 +00:00
co-authored by Claude Fable 5.1
parent f2a44507d4
commit 1a009a2113
6 changed files with 46 additions and 5 deletions
+12 -2
View File
@@ -370,6 +370,14 @@ fn source_line(article: &Article) -> String {
}
}
/// The index's meta lead: the author, when known, ahead of [`source_line`].
fn index_source_line(article: &Article) -> String {
match article.author_label() {
Some(author) => format!("{author} · {}", source_line(article)),
None => source_line(article),
}
}
/// "In This Issue": per section, each article's title, source, reading time and
/// summary, linked to its chapter (§3.10).
pub fn render_in_this_issue(issue: &Issue) -> Result<Chapter, EpubError> {
@@ -382,7 +390,7 @@ pub fn render_in_this_issue(issue: &Issue) -> Result<Chapter, EpubError> {
.map(|pick| IndexEntry {
href: article_href(pick),
title: pick.article.title.clone(),
source: source_line(&pick.article),
source: index_source_line(&pick.article),
reading_minutes: pick.article.reading_minutes(),
summary: summary_for(issue, pick).unwrap_or_default().to_string(),
why: pick.why.clone(),
@@ -891,14 +899,16 @@ mod tests {
let mut issue = issue();
issue.lineup.picks[0].article.publication = Some("Example Journal".into());
issue.lineup.picks[1].article.publication = Some("Example Feed".into());
issue.lineup.picks[1].article.author = Some("example feed".into());
let index = render_in_this_issue(&issue).unwrap();
assert!(
index
.xhtml
.contains("Example Feed · Example Journal &#183; 6 min read")
.contains("A. Writer · Example Feed · Example Journal &#183; 6 min read")
);
assert!(!index.xhtml.contains("Example Feed · Example Feed"));
assert!(!index.xhtml.contains("example feed · Example Feed"));
let article = render_article(
&issue,