Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-docgen

Documentation publishing for Pudu: articles, API references, navigation, search, and static websites

0.1.0Apache-2.01

InstallClose

Sitemap.pudu

Pudu44 lines2.1 KB

GitHub ↗
1/** @Docgen.Site.Sitemap — the crawler map of published pages */2module PuduLangDocgen.Site.Sitemap34import Std.Glob as Glob5import PuduLangDocgen as Docgen6import PuduLangDocgen.Meta as Meta78/** @Docgen.Site.SitemapOptions — site address, defaults, and per-glob settings */9export type Options = { baseUrl: Str, priority: Str, changefreq: Str, files: Array[(Str, Array[(Str, Docgen.Meta)])] }1011/// The sitemap XML listing every indexable page under the base address. `modified` gives each12/// page's last change as `YYYY-MM-DD`, when known. Settings of the last matching glob win.13export fn render(pages: &Array[Docgen.Page], options: &Options, modified: &Array[(Str, Str)]) -> Str {14  var lines = ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"]15  for page in *pages {16    if page.kind == "redirect" || Meta.flag(&page.meta, "_noindex") { continue }17    var base = options.baseUrl18    var priority = options.priority19    var changefreq = options.changefreq20    for (pattern, settings) in options.files {21      if Glob.matches(pattern, page.source) || Glob.matches(pattern, page.path) {22        base = Meta.textOr(&settings, "baseUrl", base)23        priority = Meta.textOr(&settings, "priority", priority)24        changefreq = Meta.textOr(&settings, "changefreq", changefreq)25      }26    }27    let address = (if base.endsWith("/") { base } else { base + "/" }) + page.path28    lines = lines.push("  <url>")29    lines = lines.push("    <loc>" + escaped(address) + "</loc>")30    for (path, date) in *modified {31      if path == page.path && !date.isEmpty() { lines = lines.push("    <lastmod>" + escaped(date) + "</lastmod>") }32    }33    if !changefreq.isEmpty() { lines = lines.push("    <changefreq>" + escaped(changefreq) + "</changefreq>") }34    if !priority.isEmpty() { lines = lines.push("    <priority>" + escaped(priority) + "</priority>") }35    lines = lines.push("  </url>")36  }37  lines.push("</urlset>").join("\n") + "\n"38}3940/// Text escaped for XML content.41fn escaped(text: Str) -> Str {42  text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace("'", "&apos;")43}44