sitemap2md

command module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 17 Imported by: 0

README

sitemap2md

Turn a site's sitemap.xml into clean, structured Markdown for people, scripts, and AI agents.

Install

go install github.com/markosnarinian/sitemap2md@latest

Or build from source:

go build -o sitemap2md .

Usage

sitemap2md <url> [flags]

<url> may be a sitemap URL or a plain site URL:

sitemap2md https://electronjs.org                # discovers the site's sitemap
sitemap2md https://electronjs.org/sitemap.xml    # hits exactly this URL
sitemap2md -o sitemap.md example.com             # scheme optional, write to file

When the URL doesn't itself serve a sitemap (responses are content-sniffed, so an HTML homepage is never mistaken for XML), the sitemap is discovered automatically: robots.txt Sitemap: directives are consulted first, then well-known paths (/sitemap.xml, /sitemap_index.xml, /sitemap-index.xml, /wp-sitemap.xml, /sitemap.xml.gz).

URLs without a scheme use https://. An explicit http:// URL is honored but warned about.

Sitemap index files (<sitemapindex>) are followed recursively by default, their page entries merged and deduplicated. Gzipped sitemaps (.xml.gz) are decompressed transparently.

Without -o, stdout carries only the Markdown document, so scripts can consume or redirect it directly. Progress, warnings, completion feedback, and errors use stderr and never get mixed into the document:

sitemap2md electronjs.org > sitemap.md

After each run, a short completion message is printed to stderr:

Created sitemap.md with 450 pages from 1 sitemap in 2.1s.
Flags
Flag Default Description
-o, --output stdout Save Markdown to a file instead of printing it
--excerpt off Add a short main-content excerpt for each page
--excerpt-chars 300 Limit each excerpt to this many characters
--no-recursive off List child sitemaps instead of fetching them
--concurrency 8 Maximum number of requests to run at once
--timeout 30s Time limit for each HTTP request
--heading-depth 1 Number of URL path levels to use as headings (1–5)
--include Keep URLs matching this regex (repeatable)
--exclude Skip URLs matching this regex (repeatable)
--route Keep this URL path and its children (repeatable)
-v, --verbose off Show progress; repeat for per-page and HTTP details
--version Print the installed version

Filter semantics: pages must match at least one --include/--route when any are given (they form a union); --exclude then removes matches. --route /docs matches /docs and /docs/... but not /docs-old.

Use -v for friendly phase-by-phase progress. Use -vv to troubleshoot individual sitemap and excerpt failures, or -vvv to inspect HTTP requests. Excerpt failures are grouped into one warning instead of printing hundreds of similar lines.

Output format

Pages are grouped by the first segment of their URL path, one ## section per segment, sorted for deterministic output:

# Sitemap for example.com

> 42 pages · Source: https://example.com/sitemap.xml · Generated: 2026-07-17

## Top-level pages

- [/](https://example.com/) — last updated: 2026-05-01 · frequency: daily · priority: 1.0
- [/about](https://example.com/about)

## /blog

- [/blog/post-1](https://example.com/blog/post-1) — last updated: 2026-05-01

## /docs

- [/docs/intro](https://example.com/docs/intro) — last updated: 2026-06-12 · priority: 0.9

With --excerpt, each entry gains a blockquote containing the beginning of the page's main content — extracted with a Readability port (codeberg.org/readeck/go-readability), so navigation, headers, and sidebars are excluded:

- [/blog/post-1](https://example.com/blog/post-1) — last updated: 2026-05-01

  > Electron 36.0.0 has been released! It includes upgrades to Chromium, V8, and Node.js…

Pages that fail to fetch or yield no extractable content are rendered without an excerpt. One summary warning is printed to stderr; use -vv to see the affected pages.

With --no-recursive, child sitemaps of an index are not fetched and are listed under a ## Child sitemaps section instead.

Security: prompt injection

The output of this tool is designed to be read by AI agents, and everything in it originates from a remote site: sitemap XML, robots.txt, and (with --excerpt) arbitrary page content. A hostile site could try to smuggle instructions or fake document structure into an agent's context through any of those channels. sitemap2md therefore treats all remote text as untrusted and always sanitizes it:

  • Excerpts are stripped of control/zero-width characters, collapsed to a single blockquote line, and have all Markdown syntax backslash-escaped, so they cannot form links, images, code, HTML tags, or headings.
  • URLs from <loc> and robots.txt are percent-encoded where they could break out of [text](url) link syntax.
  • Metadata (lastmod, changefreq, priority) is reduced to a whitelist of expected characters and capped in length.
  • When excerpts are included, the document header carries a provenance note marking them as quoted untrusted content.

Residual advice for consumers: treat the whole document as data, not instructions; agents should keep their own instruction/data separation and never execute directives found in page-derived text; use --exclude to drop routes dominated by user-generated content when that risk matters.

License

MIT

Documentation

Overview

sitemap2md converts a site's sitemap.xml into clean, structured Markdown.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL