Add frontmatter, markdown, path, xml, rss, and web packages
Sync local packages into the registry repo and update index.json and README.md to include all 9 packages.
This commit is contained in:
101
packages/rss/lib.lux
Normal file
101
packages/rss/lib.lux
Normal file
@@ -0,0 +1,101 @@
|
||||
// rss - RSS 2.0 feed generator for Lux
|
||||
//
|
||||
// Generates valid RSS 2.0 XML feeds from structured data.
|
||||
|
||||
import xml
|
||||
|
||||
// An RSS feed item
|
||||
type Item =
|
||||
| Item(String, String, String, String, String)
|
||||
// Item(title, link, description, pubDate, guid)
|
||||
|
||||
// An RSS channel/feed
|
||||
type Feed =
|
||||
| Feed(String, String, String, String, List<Item>)
|
||||
// Feed(title, link, description, language, items)
|
||||
|
||||
// Create a feed item
|
||||
pub fn item(title: String, link: String, description: String, pubDate: String): Item =
|
||||
Item(title, link, description, pubDate, link)
|
||||
|
||||
// Create a feed item with custom GUID
|
||||
pub fn itemWithGuid(title: String, link: String, description: String, pubDate: String, guid: String): Item =
|
||||
Item(title, link, description, pubDate, guid)
|
||||
|
||||
// Create an RSS feed
|
||||
pub fn feed(title: String, link: String, description: String, items: List<Item>): Feed =
|
||||
Feed(title, link, description, "en", items)
|
||||
|
||||
// Create an RSS feed with language
|
||||
pub fn feedWithLang(title: String, link: String, description: String, language: String, items: List<Item>): Feed =
|
||||
Feed(title, link, description, language, items)
|
||||
|
||||
// Access item fields
|
||||
pub fn itemTitle(i: Item): String = match i { Item(t, _, _, _, _) => t, }
|
||||
pub fn itemLink(i: Item): String = match i { Item(_, l, _, _, _) => l, }
|
||||
pub fn itemDescription(i: Item): String = match i { Item(_, _, d, _, _) => d, }
|
||||
pub fn itemPubDate(i: Item): String = match i { Item(_, _, _, p, _) => p, }
|
||||
pub fn itemGuid(i: Item): String = match i { Item(_, _, _, _, g) => g, }
|
||||
|
||||
// Convert ISO date (2025-01-29) to RFC 822 format (29 Jan 2025 00:00:00 GMT)
|
||||
pub fn isoToRfc822(isoDate: String): String =
|
||||
if String.length(isoDate) < 10 then isoDate
|
||||
else {
|
||||
let year = String.substring(isoDate, 0, 4)
|
||||
let month = String.substring(isoDate, 5, 7)
|
||||
let day = String.substring(isoDate, 8, 10)
|
||||
let monthName = if month == "01" then "Jan"
|
||||
else if month == "02" then "Feb"
|
||||
else if month == "03" then "Mar"
|
||||
else if month == "04" then "Apr"
|
||||
else if month == "05" then "May"
|
||||
else if month == "06" then "Jun"
|
||||
else if month == "07" then "Jul"
|
||||
else if month == "08" then "Aug"
|
||||
else if month == "09" then "Sep"
|
||||
else if month == "10" then "Oct"
|
||||
else if month == "11" then "Nov"
|
||||
else "Dec"
|
||||
day + " " + monthName + " " + year + " 00:00:00 GMT"
|
||||
}
|
||||
|
||||
// Render a single item to XML string
|
||||
fn renderItemXml(i: Item): String =
|
||||
match i {
|
||||
Item(title, link, desc, pubDate, guid) =>
|
||||
xml.render(xml.el("item", [
|
||||
xml.textEl("title", title),
|
||||
xml.textEl("link", link),
|
||||
xml.textEl("description", desc),
|
||||
xml.textEl("pubDate", isoToRfc822(pubDate)),
|
||||
xml.textElAttr("guid", [xml.attr("isPermaLink", "true")], guid)
|
||||
])),
|
||||
}
|
||||
|
||||
// Render items to concatenated XML string
|
||||
fn renderItemsXml(items: List<Item>): String =
|
||||
match List.head(items) {
|
||||
None => "",
|
||||
Some(i) => renderItemXml(i) + match List.tail(items) {
|
||||
Some(rest) => renderItemsXml(rest),
|
||||
None => "",
|
||||
},
|
||||
}
|
||||
|
||||
// Render an RSS feed to XML string
|
||||
pub fn render(f: Feed): String =
|
||||
match f {
|
||||
Feed(title, link, desc, lang, items) => {
|
||||
let itemsXml = renderItemsXml(items)
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">" +
|
||||
"<channel>" +
|
||||
"<title>" + xml.escape(title) + "</title>" +
|
||||
"<link>" + xml.escape(link) + "</link>" +
|
||||
"<description>" + xml.escape(desc) + "</description>" +
|
||||
"<language>" + lang + "</language>" +
|
||||
"<generator>Lux RSS Package</generator>" +
|
||||
itemsXml +
|
||||
"</channel></rss>"
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user