From 403375c310f23c39f16615153518aebe69a820d8 Mon Sep 17 00:00:00 2001 From: Chris Jenkins Date: Tue, 3 Feb 2026 17:22:56 +0000 Subject: [PATCH] Added support for , as seen in micro.blog RSS feeds, e.g. https://www.manton.org/feed.xml --- Sources/FeedKit/FeedNamespace.swift | 10 ++++++++++ Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift | 10 ++++++++++ Tests/FeedKitTests/Resources/xml/RSS.xml | 6 +++++- Tests/FeedKitTests/Tests/RSSTests + Mocks.swift | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Sources/FeedKit/FeedNamespace.swift b/Sources/FeedKit/FeedNamespace.swift index deba1d46..2487df7b 100644 --- a/Sources/FeedKit/FeedNamespace.swift +++ b/Sources/FeedKit/FeedNamespace.swift @@ -60,6 +60,9 @@ enum FeedNamespace: CaseIterable { /// Represents the Podcast namespace, used for podcast-specific metadata /// and extensions in podcast feeds. case podcast + /// Represents the source namespace, used for Source-specific metadata + /// like markdown content. + case source // MARK: Internal @@ -86,6 +89,8 @@ enum FeedNamespace: CaseIterable { "xmlns:atom" case .podcast: "xmlns:podcast" + case .source: + "xmlns:source" } } @@ -112,6 +117,8 @@ enum FeedNamespace: CaseIterable { "http://www.w3.org/2005/Atom" case .podcast: "https://podcastindex.org/namespace/1.0" + case .source: + "http://source.scripting.com/" } } } @@ -156,6 +163,9 @@ extension FeedNamespace { case .podcast: feed.channel?.podcast != nil || feed.channel?.items?.contains(where: { $0.podcast != nil }) ?? false + + case .source: + feed.channel?.items?.contains(where: { $0.markdown != nil }) ?? false } } diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift index 4fd823f8..acf0ae0e 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift @@ -38,6 +38,7 @@ public struct RSSFeedItem { title: String? = nil, link: String? = nil, description: String? = nil, + markdown: String? = nil, author: String? = nil, categories: [RSSFeedCategory]? = nil, comments: String? = nil, @@ -55,6 +56,7 @@ public struct RSSFeedItem { self.title = title self.link = link self.description = description + self.markdown = markdown self.author = author self.categories = categories self.comments = comments @@ -89,6 +91,11 @@ public struct RSSFeedItem { /// Cinema was being staged. public var description: String? + /// The markdown content for the item. + /// + /// Example: ## Highlights + public var markdown: String? + /// Email address of the author of the item. /// /// Example: oprah\@oxygen.net @@ -254,6 +261,7 @@ extension RSSFeedItem: Codable { case title case link case description + case markdown = "source:markdown" case author case category case comments @@ -275,6 +283,7 @@ extension RSSFeedItem: Codable { title = try container.decodeIfPresent(String.self, forKey: CodingKeys.title) link = try container.decodeIfPresent(String.self, forKey: CodingKeys.link) description = try container.decodeIfPresent(String.self, forKey: CodingKeys.description) + markdown = try container.decodeIfPresent(String.self, forKey: CodingKeys.markdown) author = try container.decodeIfPresent(String.self, forKey: CodingKeys.author) categories = try container.decodeIfPresent([RSSFeedCategory].self, forKey: CodingKeys.category) comments = try container.decodeIfPresent(String.self, forKey: CodingKeys.comments) @@ -296,6 +305,7 @@ extension RSSFeedItem: Codable { try container.encodeIfPresent(title, forKey: CodingKeys.title) try container.encodeIfPresent(link, forKey: CodingKeys.link) try container.encodeIfPresent(description, forKey: CodingKeys.description) + try container.encodeIfPresent(markdown, forKey: CodingKeys.markdown) try container.encodeIfPresent(author, forKey: CodingKeys.author) try container.encodeIfPresent(categories, forKey: CodingKeys.category) try container.encodeIfPresent(comments, forKey: CodingKeys.comments) diff --git a/Tests/FeedKitTests/Resources/xml/RSS.xml b/Tests/FeedKitTests/Resources/xml/RSS.xml index 78df69a2..4a1fc3f6 100644 --- a/Tests/FeedKitTests/Resources/xml/RSS.xml +++ b/Tests/FeedKitTests/Resources/xml/RSS.xml @@ -1,5 +1,5 @@ - + Iris http://www.iris.news/ @@ -50,6 +50,10 @@ 1983/V http://dallas.example.com/feedback/1983/06/joebob.htm I'm headed for France. I wasn't gonna go this year, but then last week "Valley Girl" came out and I said to myself, Joe Bob, you gotta get out of the country for a while. + tag:dallas.example.com,4131:news Fri, 05 Oct 2007 09:00:00 CST diff --git a/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift b/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift index 549af807..b3f79cc7 100644 --- a/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift @@ -93,6 +93,7 @@ extension RSSTests { title: "Seventh Heaven! Ryan Hurls Another No Hitter", link: "http://dallas.example.com/1991/05/02/nolan.htm", description: "I'm headed for France. I wasn't gonna go this year, but then last week \"Valley Girl\" came out and I said to myself, Joe Bob, you gotta get out of the country for a while.", + markdown: "## Highlights\n\n- Traveled to France.\n- Talked about \"Valley Girl\".", author: "jbb@dallas.example.com (Joe Bob Briggs)", categories: [ .init(