From 596ea2677497e40baf228e7c7bb9691f11a5375a Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 14 Jan 2026 20:45:36 +0000 Subject: [PATCH 1/2] Add subtitle field to feed fields - Add 'subtitle' to fields.feed array in lib/fields.js - Add subtitle property to TypeScript Output interface in index.d.ts Co-authored-by: openhands --- index.d.ts | 1 + lib/fields.js | 1 + 2 files changed, 2 insertions(+) diff --git a/index.d.ts b/index.d.ts index 45b237a..21ed94d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -59,6 +59,7 @@ declare namespace Parser { items: (U & Item)[]; feedUrl?: string; description?: string; + subtitle?: string; itunes?: { [key: string]: any; image?: string; diff --git a/lib/fields.js b/lib/fields.js index b3f8d7b..f3df0ef 100644 --- a/lib/fields.js +++ b/lib/fields.js @@ -9,6 +9,7 @@ fields.feed = [ ['dc:type', 'type'], 'title', 'description', + 'subtitle', 'author', 'pubDate', 'webMaster', From 9526db5d7d6fcdd272b130af4d669e2f5bc1687b Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 14 Jan 2026 20:51:01 +0000 Subject: [PATCH 2/2] Add tests for subtitle field parsing in RSS and Atom feeds - Add subtitle parsing support for Atom feeds in buildAtomFeed() - Create test input files for RSS and Atom feeds with subtitle - Create expected output JSON files for subtitle tests - Add test cases for parsing subtitle from RSS and Atom feeds - Update existing test output files (heise, feedburner, many-links) to include subtitle field Co-authored-by: openhands --- lib/parser.js | 6 ++++++ test/input/subtitle-atom.atom | 30 ++++++++++++++++++++++++++++++ test/input/subtitle-rss.rss | 21 +++++++++++++++++++++ test/output/feedburner.json | 1 + test/output/heise.json | 1 + test/output/many-links.json | 1 + test/output/subtitle-atom.json | 31 +++++++++++++++++++++++++++++++ test/output/subtitle-rss.json | 26 ++++++++++++++++++++++++++ test/parser.js | 8 ++++++++ 9 files changed, 125 insertions(+) create mode 100644 test/input/subtitle-atom.atom create mode 100644 test/input/subtitle-rss.rss create mode 100644 test/output/subtitle-atom.json create mode 100644 test/output/subtitle-rss.json diff --git a/lib/parser.js b/lib/parser.js index 6aaccb0..22e6b83 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -145,6 +145,12 @@ class Parser { if (title._) title = title._ if (title) feed.title = title; } + // The subtitle field is used in Atom feeds to provide a secondary description or tagline for the feed + if (xmlObj.feed.subtitle) { + let subtitle = xmlObj.feed.subtitle[0] || ''; + if (subtitle._) subtitle = subtitle._; + if (subtitle) feed.subtitle = subtitle; + } if (xmlObj.feed.updated) { feed.lastBuildDate = xmlObj.feed.updated[0]; } diff --git a/test/input/subtitle-atom.atom b/test/input/subtitle-atom.atom new file mode 100644 index 0000000..2fb158e --- /dev/null +++ b/test/input/subtitle-atom.atom @@ -0,0 +1,30 @@ + + + Test Atom Feed with Subtitle + A secondary description for the Atom feed + + + 2024-01-02T12:00:00Z + http://example.com/feed + + Test Author + + + Test Entry 1 + + http://example.com/entry1 + 2024-01-01T12:00:00Z + 2024-01-01T12:00:00Z + Summary of entry 1 + Content of entry 1 + + + Test Entry 2 + + http://example.com/entry2 + 2024-01-02T12:00:00Z + 2024-01-02T12:00:00Z + Summary of entry 2 + Content of entry 2 + + diff --git a/test/input/subtitle-rss.rss b/test/input/subtitle-rss.rss new file mode 100644 index 0000000..102dc8a --- /dev/null +++ b/test/input/subtitle-rss.rss @@ -0,0 +1,21 @@ + + + + Test RSS Feed with Subtitle + A secondary description for the RSS feed + Main description of the feed + http://example.com + + Test Item 1 + http://example.com/item1 + Description of item 1 + Mon, 01 Jan 2024 12:00:00 GMT + + + Test Item 2 + http://example.com/item2 + Description of item 2 + Tue, 02 Jan 2024 12:00:00 GMT + + + diff --git a/test/output/feedburner.json b/test/output/feedburner.json index d21642c..28067e4 100644 --- a/test/output/feedburner.json +++ b/test/output/feedburner.json @@ -255,6 +255,7 @@ "link": "http://googleadsdeveloper.blogspot.com/search/label/adwords_api", "feedUrl": "http://www.blogger.com/feeds/7815614485808579332/posts/default/-/adwords_api/-/adwords_api?start-index=26&max-results=25", "title": "Google Ads Developer Blog", + "subtitle": "The official blog for information about the AdWords, AdSense, DoubleClick and AdMob APIs and SDKs.", "lastBuildDate": "2016-06-27T07:36:54.007-07:00" } } \ No newline at end of file diff --git a/test/output/heise.json b/test/output/heise.json index 79e1fed..f04770e 100644 --- a/test/output/heise.json +++ b/test/output/heise.json @@ -155,6 +155,7 @@ "link": "http://www.heise.de/developer/", "feedUrl": "http://www.heise.de/developer/rss/news-atom.xml", "title": "heise developer neueste Meldungen", + "subtitle": "Informationen für Entwickler", "lastBuildDate": "2016-02-01T17:54:50+01:00" } } \ No newline at end of file diff --git a/test/output/many-links.json b/test/output/many-links.json index cd5cc5f..6c5366d 100644 --- a/test/output/many-links.json +++ b/test/output/many-links.json @@ -255,6 +255,7 @@ "link": "http://testing.googleblog.com/", "feedUrl": "http://www.blogger.com/feeds/15045980/posts/default?start-index=26&max-results=25&redirect=false", "title": "Google Testing Blog", + "subtitle": "If it ain't broke, you're not trying hard enough.", "lastBuildDate": "2017-10-18T03:40:38.732-07:00" } } \ No newline at end of file diff --git a/test/output/subtitle-atom.json b/test/output/subtitle-atom.json new file mode 100644 index 0000000..e5ba524 --- /dev/null +++ b/test/output/subtitle-atom.json @@ -0,0 +1,31 @@ +{ + "feed": { + "items": [ + { + "title": "Test Entry 1", + "link": "http://example.com/entry1", + "pubDate": "2024-01-01T12:00:00.000Z", + "content": "Content of entry 1", + "contentSnippet": "Content of entry 1", + "summary": "Summary of entry 1", + "id": "http://example.com/entry1", + "isoDate": "2024-01-01T12:00:00.000Z" + }, + { + "title": "Test Entry 2", + "link": "http://example.com/entry2", + "pubDate": "2024-01-02T12:00:00.000Z", + "content": "Content of entry 2", + "contentSnippet": "Content of entry 2", + "summary": "Summary of entry 2", + "id": "http://example.com/entry2", + "isoDate": "2024-01-02T12:00:00.000Z" + } + ], + "link": "http://example.com", + "feedUrl": "http://example.com/feed.atom", + "title": "Test Atom Feed with Subtitle", + "subtitle": "A secondary description for the Atom feed", + "lastBuildDate": "2024-01-02T12:00:00Z" + } +} diff --git a/test/output/subtitle-rss.json b/test/output/subtitle-rss.json new file mode 100644 index 0000000..7543b9b --- /dev/null +++ b/test/output/subtitle-rss.json @@ -0,0 +1,26 @@ +{ + "feed": { + "items": [ + { + "title": "Test Item 1", + "link": "http://example.com/item1", + "pubDate": "Mon, 01 Jan 2024 12:00:00 GMT", + "content": "Description of item 1", + "contentSnippet": "Description of item 1", + "isoDate": "2024-01-01T12:00:00.000Z" + }, + { + "title": "Test Item 2", + "link": "http://example.com/item2", + "pubDate": "Tue, 02 Jan 2024 12:00:00 GMT", + "content": "Description of item 2", + "contentSnippet": "Description of item 2", + "isoDate": "2024-01-02T12:00:00.000Z" + } + ], + "title": "Test RSS Feed with Subtitle", + "description": "Main description of the feed", + "subtitle": "A secondary description for the RSS feed", + "link": "http://example.com" + } +} diff --git a/test/parser.js b/test/parser.js index 034c72f..7ca3150 100644 --- a/test/parser.js +++ b/test/parser.js @@ -284,4 +284,12 @@ describe('Parser', function() { it('should parse atom:link pagination links', function (done) { testParseForFile('pagination-links', 'rss', done); }); + + it('should parse subtitle field from RSS feed', function(done) { + testParseForFile('subtitle-rss', 'rss', done); + }); + + it('should parse subtitle field from Atom feed', function(done) { + testParseForFile('subtitle-atom', 'atom', done); + }); })