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:
2026-02-24 21:04:20 -05:00
parent c5a2276f6e
commit cbb66fbb73
42 changed files with 3844 additions and 0 deletions

109
packages/xml/lib.lux Normal file
View File

@@ -0,0 +1,109 @@
// xml - XML builder for Lux
//
// Provides a simple API for constructing well-formed XML documents.
// Designed for generating RSS feeds, sitemaps, and other XML output.
// An XML attribute (key-value pair)
type Attr =
| Attr(String, String)
// An XML node: element with tag, attributes, and children, or text content
type Node =
| Element(String, List<Attr>, List<Node>)
| Text(String)
| CData(String)
| Raw(String)
// Escape special XML characters in text content
pub fn escape(s: String): String =
String.replace(
String.replace(
String.replace(
String.replace(
String.replace(s, "&", "&amp;"),
"<", "&lt;"),
">", "&gt;"),
"\"", "&quot;"),
"'", "&apos;")
// Create a text node
pub fn text(content: String): Node = Text(content)
// Create a CDATA section
pub fn cdata(content: String): Node = CData(content)
// Create a raw (unescaped) node
pub fn raw(content: String): Node = Raw(content)
// Create an element with tag, attributes, and children
pub fn element(tag: String, attrs: List<Attr>, children: List<Node>): Node =
Element(tag, attrs, children)
// Create an element with no attributes
pub fn el(tag: String, children: List<Node>): Node =
Element(tag, [], children)
// Create a self-closing element with attributes and no children
pub fn selfClosing(tag: String, attrs: List<Attr>): Node =
Element(tag, attrs, [])
// Create an attribute
pub fn attr(key: String, value: String): Attr =
Attr(key, value)
// Create an element with text content
pub fn textEl(tag: String, content: String): Node =
Element(tag, [], [Text(content)])
// Create an element with attributes and text content
pub fn textElAttr(tag: String, attrs: List<Attr>, content: String): Node =
Element(tag, attrs, [Text(content)])
// Render a single attribute to string
fn renderAttr(a: Attr): String =
match a {
Attr(k, v) => " " + k + "=\"" + escape(v) + "\"",
}
// Render a list of attributes to string
fn renderAttrs(attrs: List<Attr>): String =
match List.head(attrs) {
None => "",
Some(a) => renderAttr(a) + match List.tail(attrs) {
Some(rest) => renderAttrs(rest),
None => "",
},
}
// Render child nodes to string
fn renderChildren(nodes: List<Node>): String =
match List.head(nodes) {
None => "",
Some(node) => render(node) + match List.tail(nodes) {
Some(rest) => renderChildren(rest),
None => "",
},
}
// Render a node to an XML string
pub fn render(node: Node): String =
match node {
Element(tag, attrs, children) => {
let attrStr = renderAttrs(attrs)
if List.length(children) == 0 then
"<" + tag + attrStr + "/>"
else
"<" + tag + attrStr + ">" + renderChildren(children) + "</" + tag + ">"
},
Text(content) => escape(content),
CData(content) => "<![CDATA[" + content + "]]>",
Raw(content) => content,
}
// Render a complete XML document with declaration
pub fn document(root: Node): String =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + render(root)
// Render with a custom declaration (e.g., for RSS stylesheets)
pub fn documentWithDecl(decl: String, root: Node): String =
decl + "\n" + render(root)