// RSS 2.0 and Atom feeds for the blog posts, emitted as feed.xml and // atom.xml by main.typ. Entries are built from the metadata in // site-info.pages (newest first). #import "/global/common.typ": baseurl #let xml-escape(s) = s.replace("&", "&").replace("<", "<").replace(">", ">") // ISO date ("2026-07-28") to RFC 822 ("Tue, 28 Jul 2026 00:00:00 GMT"). #let rfc822(iso) = { let (y, m, d) = iso.split("-").map(int) datetime(year: y, month: m, day: d).display( "[weekday repr:short], [day] [month repr:short] [year] 00:00:00 GMT" ) } // ISO date ("2026-07-28") to RFC 3339 ("2026-07-28T00:00:00Z"). #let rfc3339(iso) = iso + "T00:00:00Z" #let _entries(site-info, item-fn) = { let pages = site-info.pages let ids = pages.keys().filter(k => k.starts-with("post/")) let entries = () for id in ids { let p = pages.at(id) let title = if "long-title" in p { p.long-title } else { p.title } let url = baseurl + "/" + id + ".html" entries.push(item-fn(title, url, p)) } entries } #let feed-xml(site-info) = { let items = _entries(site-info, (title, url, p) => { let lines = ( " ", " " + xml-escape(title) + "", " " + url + "", " " + url + "", ) if "date" in p { lines.push(" " + rfc822(p.date) + "") } if "description" in p { lines.push(" " + xml-escape(p.description) + "") } lines.push(" ") lines.join("\n") }) ( "", "", "", " " + xml-escape(site-info.title) + "", " " + baseurl + "/", " Posts from " + xml-escape(site-info.title) + " (" + baseurl + ")", items.join("\n"), "", "", "", ).join("\n") } // Atom (RFC 4287) feed, emitted as atom.xml by main.typ. #let atom-xml(site-info) = { let entries = _entries(site-info, (title, url, p) => { let lines = ( " ", " " + xml-escape(title) + "", " ", " " + url + "", ) if "date" in p { lines.push(" " + rfc3339(p.date) + "") } if "description" in p { lines.push(" " + xml-escape(p.description) + "") } lines.push(" ") lines.join("\n") }) // newest post first, so its date is the feed's last-update time let updated = rfc3339(site-info.pages.at( site-info.pages.keys().filter(k => k.starts-with("post/")).first() ).date) ( "", "", " " + xml-escape(site-info.title) + "", " ", " ", " " + baseurl + "/", " " + updated + "", " ", " Kumar", " ", entries.join("\n"), "", "", ).join("\n") }