diff options
| author | Sam Scholten | 2026-08-30 20:40:39 +1000 |
|---|---|---|
| committer | Sam Scholten | 2026-08-30 20:40:39 +1000 |
| commit | 49d9f3e0eaeeab234c3ec903be43b88919d98eff (patch) | |
| tree | d44472e50119dd8ef9ab406a65b0f6b16a4daf7a /cmds | |
| parent | eff960c54620bfba47d40bc3792ba805dea3dab3 (diff) | |
| download | fluxrec-49d9f3e0eaeeab234c3ec903be43b88919d98eff.tar.gz fluxrec-49d9f3e0eaeeab234c3ec903be43b88919d98eff.zip | |
rss: render score head as HTML paragraph
Descriptions render as sanitized HTML in readers, where bare newlines
collapse and the feed/score line ran into the article text. Wrap the
headline in <p><em> so it breaks cleanly and reads as metadata, escaped
on the wire by encoding/xml as description-carried HTML should be.
Diffstat (limited to 'cmds')
| -rw-r--r-- | cmds/rss.go | 23 | ||||
| -rw-r--r-- | cmds/rss_test.go | 6 |
2 files changed, 18 insertions, 11 deletions
diff --git a/cmds/rss.go b/cmds/rss.go index 8679f6f..30be578 100644 --- a/cmds/rss.go +++ b/cmds/rss.go @@ -49,8 +49,9 @@ type rssDocument struct { // RSS 2.0 document. Each item title gets the source feed as a rune-capped // suffix (readers show the channel title as the source of every item, so // this is the only in-list provenance), and the description body opens -// with feed + model score + the batch-wide median score. Item content was -// already cleaned when the run row was written. +// with feed + model score + the batch-wide median score as an emphasized +// HTML paragraph (bare newlines collapse where descriptions render as +// HTML). Item content was already cleaned when the run row was written. func RenderRSS(runs []core.RunRow) ([]byte, error) { doc := rssDocument{ Version: "2.0", @@ -95,9 +96,14 @@ func truncateRunes(s string, max int) string { return string([]rune(s)[:max]) + "…" } -// rssDescription builds the item body: first a headline line with the -// source feed, model score, and batch-wide median (omitted for run rows -// written before the median was logged), then the cleaned content (if any). +// rssDescription builds the item body: first a headline with the source +// feed, model score, and batch-wide median (omitted for run rows written +// before the median was logged), then the cleaned content (if any). The +// headline is wrapped in an emphasized HTML paragraph: descriptions render +// as sanitized HTML in most readers, where bare newlines collapse and the +// metadata line would run into the article text. encoding/xml escapes the +// tags on the wire, which is exactly how description-carried HTML is meant +// to be transported. func rssDescription(k core.KeptItem, median *float64) string { head := fmt.Sprintf("score %.2f", k.Score) if median != nil { @@ -106,8 +112,9 @@ func rssDescription(k core.KeptItem, median *float64) string { if k.FeedTitle != "" { head = k.FeedTitle + " · " + head } - if k.Content == "" { - return head + body := "<p><em>" + head + "</em></p>" + if k.Content != "" { + body += "\n" + k.Content } - return head + "\n\n" + k.Content + return body } diff --git a/cmds/rss_test.go b/cmds/rss_test.go index ca216ca..79d6d37 100644 --- a/cmds/rss_test.go +++ b/cmds/rss_test.go @@ -51,21 +51,21 @@ func TestRenderRSSGolden(t *testing.T) { <link>https://example.com/c</link> <guid isPermaLink="false">mf:103</guid> <pubDate>Fri, 01 Mar 2024 11:00:00 +0000</pubDate> - <description>Feed A · score 0.80</description> + <description><p><em>Feed A · score 0.80</em></p></description> </item> <item> <title>Alpha & Omega — Feed A</title> <link>https://example.com/a?x=1&y=2</link> <guid isPermaLink="false">mf:101</guid> <pubDate>Fri, 01 Mar 2024 05:00:00 +0000</pubDate> - <description>Feed A · score 0.90 · batch median 0.55

x < y</description> + <description><p><em>Feed A · score 0.90 · batch median 0.55</em></p>
x < y</description> </item> <item> <title>Beta — A Feed With An Extremely Long And Descri…</title> <link>https://example.com/b</link> <guid isPermaLink="false">mf:102</guid> <pubDate>Fri, 01 Mar 2024 05:30:00 +0000</pubDate> - <description>A Feed With An Extremely Long And Descriptive Title Here · score 0.20 · batch median 0.55

second body</description> + <description><p><em>A Feed With An Extremely Long And Descriptive Title Here · score 0.20 · batch median 0.55</em></p>
second body</description> </item> </channel> </rss>` |
