81 lines
2.4 KiB
Typst
81 lines
2.4 KiB
Typst
#import "./summary.typ": summary-sort-key
|
|
|
|
// TODO DOCUMENT
|
|
|
|
#let xml-tag(
|
|
name,
|
|
attrs: (),
|
|
children: none,
|
|
body: none,
|
|
) = {
|
|
assert(not ((children != none) and (body != none)), message: "children and body cannot be set at the same time")
|
|
|
|
("<" + name
|
|
+ if attrs.len() != 0 { " " } else { "" }
|
|
+ attrs.map(attr => attr.at(0) + "=\"" + attr.at(1) + "\"").join(" ")
|
|
+ if children == none and body == none { "/>" } else if children != none {
|
|
(
|
|
">\n " + children.join("\n").replace("\n", "\n ") +
|
|
"\n</" + name + ">"
|
|
)
|
|
} else if body != none {
|
|
">" + body + "</" + name + ">"
|
|
} else {
|
|
panic("children and body cannot be set at the same time")
|
|
})
|
|
}
|
|
|
|
// We don't care about the hour, but RFC 822 requires it, so use 0 and GMT
|
|
#let date-format-rfc822 = "[day padding:zero] [month repr:short] [year repr:full] 00:00:01 +0000"
|
|
|
|
#let rss(
|
|
title,
|
|
link,
|
|
description,
|
|
rss-url,
|
|
summaries,
|
|
language: "en-us",
|
|
managing-editor: none,
|
|
webmaster: none,
|
|
) = {
|
|
let channel-element = (
|
|
xml-tag("title", body: title),
|
|
xml-tag("link", body: link),
|
|
xml-tag("description", body: description),
|
|
xml-tag("language", body: language),
|
|
xml-tag("lastBuildDate", body: datetime.today().display(date-format-rfc822)),
|
|
xml-tag("docs", body: "https://www.rssboard.org/rss-specification"),
|
|
xml-tag("generator", body: "Some random Typst scrypt"),
|
|
xml-tag("atom:link", attrs: (
|
|
("href", rss-url),
|
|
("rel", "self"),
|
|
("type", "application/rss+xml")
|
|
)),
|
|
)
|
|
if managing-editor != none {
|
|
channel-element.push(xml-tag("managingEditor", body: managing-editor))
|
|
}
|
|
if webmaster != none {
|
|
channel-element.push(xml-tag("webMaster", body: webmaster))
|
|
}
|
|
let items = summaries.sorted(
|
|
key: summary-sort-key
|
|
).map(it => xml-tag(
|
|
"item",
|
|
children: (
|
|
xml-tag("title", body: it.document-args.title),
|
|
xml-tag("link", body: it.template-args.url),
|
|
xml-tag("guid", body: it.template-args.url),
|
|
xml-tag("description", body: it.document-args.description),
|
|
xml-tag("pubDate", body: it.document-args.date.display(date-format-rfc822)),
|
|
) + it.template-args.tags.map(tag => xml-tag("category", body: tag))
|
|
))
|
|
xml-tag(
|
|
"rss",
|
|
attrs: (
|
|
("xmlns:atom", "http://www.w3.org/2005/Atom"),
|
|
("version","2.0")
|
|
),
|
|
children: (xml-tag("channel", children: channel-element + items),)
|
|
)
|
|
}
|