clapdown 0.3.0

Generate well-structured Markdown documentation from a clap CLI.
Documentation

clapdown

CI crates.io docs.rs

Generate well-structured Markdown documentation from a clap CLI.

clapdown walks a clap::Command and renders it to Markdown whose heading outline tracks command nesting without ever skipping a level: the root command is a top-level heading, each subcommand descends exactly one level, and a command's Arguments/Options sections sit one level below the command. Arguments render as definition lists by default, or as bullet lists with Flavor::CommonMark.

It is inspired by clap-markdown but fixes that crate's malformed heading outline (which jumps h1 -> h2 -> h6 and renders every subcommand as a flat h2) and is built around an output-flavor abstraction.

Usage

Add the crate (typically as a build-dependency, since generating docs from a clap::Command is a build-time concern):

[build-dependencies]
clapdown = "0.2"
clap = { version = "4", features = ["derive"] }

Render from a derived CLI type:

use clap::CommandFactory;

let options = clapdown::Options::new()
    .base_heading_level(1)
    .footer(false);

let markdown = clapdown::render(&Cli::command(), &options);

or go straight from the type:

let markdown = clapdown::render_from::<Cli>(&clapdown::Options::new());

Options

Method Default Effect
flavor(Flavor) Mdbook Target Markdown flavor.
base_heading_level(u8) 1 Heading level of the root command.
title(impl Into<String>) command name Override the root heading (Pandoc: title).
table_of_contents(bool) false Emit a nested table of contents.
footer(bool) false Emit an attribution footer.
aliases(bool) true Show command aliases.
metadata(bool) true Emit the Pandoc YAML metadata block.
metadata_field(key, value) none Add a custom Pandoc metadata field.
metadata_field_with_style(key, value, style) none Choose how a metadata value is written.

Flavors

Flavor::Mdbook and Flavor::Pandoc emit definition lists, which render natively in mdBook (enabled by default) and in Pandoc. The Flavor enum is #[non_exhaustive].

Flavor::CommonMark uses bullet lists with bold argument terms and indented descriptions, defaults, and possible values. It works with CommonMark and GitHub-flavored Markdown without extensions and emits no YAML metadata.

Flavor::Pandoc additionally prefixes the document with a YAML metadata block carrying the title (from title(...), else the command name) plus any metadata_field(...) entries. Because the title lives in the metadata, the root command's h1 is omitted from the body to avoid duplicating it. Disable the block with metadata(false), in which case Pandoc output matches Mdbook.

---
title: demo
author: Jane Doe
---

Metadata values preserve newlines, including trailing newlines. Single-line values use plain or quoted YAML scalars, while multiline values use literal blocks with the appropriate chomping indicator (|-, |, or |+).

To request a paragraph explicitly, choose MetadataStyle::Folded (>):

let options = clapdown::Options::new()
    .flavor(clapdown::Flavor::Pandoc)
    .metadata_field_with_style(
        "description",
        "Comprehensive reference for the CLI, including all commands and options.",
        clapdown::MetadataStyle::Folded,
    );
description: >
  Comprehensive reference for the CLI, including all commands and options.

Use MetadataStyle::Literal (|) to preserve line breaks and indentation. Both explicit block styles retain at least one trailing newline for nonempty values, so Pandoc can render ordinary text as a paragraph. Folded blocks turn ordinary line breaks into spaces. Literal blocks preserve Markdown paragraphs, lists, and code fences. The YAML | indicator does not make the value a code block in Pandoc; include Markdown code fences or indentation for verbatim text.

License

Licensed under either of MIT or Apache-2.0 at your option.