Man Pages
Overview
Section titled “Overview”Generate Unix manual pages from CLI definitions using clap_mangen.
Add Dependencies
Section titled “Add Dependencies”[dependencies]clap = { version = "4.5", features = ["derive"] }
[build-dependencies]clap = { version = "4.5", features = ["derive"] }clap_mangen = "0.2"Build Script
Section titled “Build Script”build.rs:
use clap::CommandFactory;use clap_mangen::Man;use std::fs;use std::path::PathBuf;
include!("src/cli.rs");
fn main() { let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); let man_dir = out_dir.join("man"); fs::create_dir_all(&man_dir).unwrap();
let cmd = Cli::command(); let man = Man::new(cmd); let mut buffer = Vec::new(); man.render(&mut buffer).unwrap();
fs::write(man_dir.join("rust-template.1"), buffer).unwrap();
println!("cargo:rerun-if-changed=src/cli.rs");}CLI Definition
Section titled “CLI Definition”src/cli.rs:
use clap::Parser;
/// Modern Rust project template with production-ready tooling////// This tool provides a comprehensive starting point for Rust projects,/// including CI/CD workflows, security scanning, and multi-platform support.#[derive(Parser, Debug)]#[command(name = "rust-template")]#[command(author = "Your Name <email@example.com>")]#[command(version)]#[command(about, long_about = None)]pub struct Cli { /// Path to configuration file /// /// Specifies a custom configuration file location. /// If not provided, defaults to ./config.toml #[arg(short, long, value_name = "FILE")] pub config: Option<String>,
/// Enable verbose output /// /// Increases verbosity of logging output. /// Can be specified multiple times for more verbosity. #[arg(short, long, action = clap::ArgAction::Count)] pub verbose: u8,
/// Quiet mode (suppress output) #[arg(short, long, conflicts_with = "verbose")] pub quiet: bool,}Installation
Section titled “Installation”System-Wide
Section titled “System-Wide”# Build projectcargo build --release
# Copy man pagesudo cp target/release/build/rust-template-*/out/man/rust-template.1 \ /usr/local/share/man/man1/
# Update man databasesudo mandbUser Installation
Section titled “User Installation”# Create user man directorymkdir -p ~/.local/share/man/man1
# Copy man pagecp target/release/build/rust-template-*/out/man/rust-template.1 \ ~/.local/share/man/man1/
# Add to MANPATH in ~/.bashrc or ~/.zshrcexport MANPATH="$HOME/.local/share/man:$MANPATH"
# Update databasemandb ~/.local/share/manView Man Page
Section titled “View Man Page”man rust-templatePackage Integration
Section titled “Package Integration”Debian Package
Section titled “Debian Package”Cargo.toml:
[package.metadata.deb]assets = [ ["target/release/rust-template", "usr/bin/", "755"], ["target/release/build/rust-template-*/out/man/rust-template.1", "usr/share/man/man1/", "644"],]RPM Package
Section titled “RPM Package”Cargo.toml:
[package.metadata.generate-rpm]assets = [ { source = "target/release/rust-template", dest = "/usr/bin/", mode = "755" }, { source = "target/release/build/rust-template-*/out/man/rust-template.1", dest = "/usr/share/man/man1/", mode = "644" },]Homebrew Formula
Section titled “Homebrew Formula”def install system "cargo", "install", *std_cargo_args
# Install man page man1.install "target/release/build/rust-template-*/out/man/rust-template.1"endAdvanced Features
Section titled “Advanced Features”Multiple Sections
Section titled “Multiple Sections”use clap_mangen::Man;
fn main() { let cmd = Cli::command();
// Section 1: User commands let man1 = Man::new(cmd.clone()).section("1"); fs::write("man/rust-template.1", man1.render()).unwrap();
// Section 5: File formats (config) let man5 = Man::new(cmd.clone()) .section("5") .title("rust-template.conf"); fs::write("man/rust-template.conf.5", man5.render()).unwrap();}Subcommand Man Pages
Section titled “Subcommand Man Pages”use clap::{Parser, Subcommand};
#[derive(Parser)]struct Cli { #[command(subcommand)] command: Commands,}
#[derive(Subcommand)]enum Commands { /// Initialize a new project Init { /* ... */ }, /// Build the project Build { /* ... */ },}
// build.rsfn main() { let cmd = Cli::command();
// Main command let man = Man::new(cmd.clone()); fs::write("man/rust-template.1", man.render()).unwrap();
// Subcommands for subcmd in cmd.get_subcommands() { let name = format!("rust-template-{}", subcmd.get_name()); let man = Man::new(subcmd.clone()).title(&name); fs::write(format!("man/{}.1", name), man.render()).unwrap(); }}Results in:
rust-template.1- Main commandrust-template-init.1- Init subcommandrust-template-build.1- Build subcommand
Custom Sections
Section titled “Custom Sections”use clap_mangen::roff::{Roff, roman};
let mut man = Man::new(cmd);
// Add EXAMPLES sectionlet examples = vec![ roman("Basic usage:"), roman(""), roman(" rust-template --config myconfig.toml"), roman(""), roman("Verbose mode:"), roman(""), roman(" rust-template -vvv"),];
man.push_examples(&examples);Man Page Sections
Section titled “Man Page Sections”Standard Sections
Section titled “Standard Sections”- NAME - Command name and one-line description
- SYNOPSIS - Command syntax
- DESCRIPTION - Detailed description
- OPTIONS - Command-line options
- EXAMPLES - Usage examples
- AUTHORS - Author information
- SEE ALSO - Related commands
- BUGS - Bug reporting information
Customization
Section titled “Customization”/// # Examples////// Basic usage:/// rust-template --config config.toml////// Verbose mode:/// rust-template -vvv////// # See Also////// Related documentation at https://docs.rs/rust-template////// # Bugs////// Report bugs at https://github.com/user/rust-template/issues#[derive(Parser)]#[command(after_help = "EXAMPLES:\n rust-template --config config.toml\n\nSEE ALSO:\n https://docs.rs/rust-template")]pub struct Cli { // ...}Formatting
Section titled “Formatting”Emphasis
Section titled “Emphasis”/// Enable **bold text** or *italic text* in descriptions////// Use `code` for inline code#[arg(long)]pub option: bool,/// Multiple options:////// - Option 1: Description/// - Option 2: Description/// - Option 3: Description#[arg(long)]pub option: String,Code Blocks
Section titled “Code Blocks”/// Example usage:////// rust-template --config config.toml/// rust-template --verbose#[arg(long)]pub option: bool,Testing
Section titled “Testing”Verify Generation
Section titled “Verify Generation”# Buildcargo build
# Find generated man pagefind target -name "*.1"
# Viewman target/release/build/rust-template-*/out/man/rust-template.1Lint Man Page
Section titled “Lint Man Page”# Install groffsudo apt install groff # Debian/Ubuntubrew install groff # macOS
# Check for errorsgroff -man -Tutf8 rust-template.1Automated Testing
Section titled “Automated Testing”#[test]fn verify_man_page() { let out_dir = std::env::var("OUT_DIR").unwrap(); let man_file = format!("{}/man/rust-template.1", out_dir); assert!(std::path::Path::new(&man_file).exists());}Viewing Man Pages
Section titled “Viewing Man Pages”Local Development
Section titled “Local Development”# View directlyman target/release/build/rust-template-*/out/man/rust-template.1
# Or add to MANPATH temporarilyexport MANPATH="$PWD/target/release/build/rust-template-*/out/man:$MANPATH"man rust-templateHTML Generation
Section titled “HTML Generation”# Convert to HTMLgroff -man -Thtml rust-template.1 > rust-template.html
# Or use pandocpandoc rust-template.1 -o rust-template.htmlPDF Generation
Section titled “PDF Generation”# Convert to PDFgroff -man -Tpdf rust-template.1 > rust-template.pdf
# Or via PostScriptgroff -man -Tps rust-template.1 | ps2pdf - rust-template.pdfBest Practices
Section titled “Best Practices”- Write detailed descriptions - Users rely on man pages
- Include examples - Show real usage patterns
- Document all options - Every flag deserves explanation
- Test rendering - View generated pages before release
- Update with code - Keep docs in sync with CLI
- Version appropriately - Man pages versioned with package
- Cross-reference - Link related commands in SEE ALSO
Troubleshooting
Section titled “Troubleshooting”Man Page Not Found
Section titled “Man Page Not Found”# Check installationman -w rust-template
# Verify MANPATHecho $MANPATH
# Rebuild man databasesudo mandbFormatting Issues
Section titled “Formatting Issues”# Check for groff errorsgroff -man -Tutf8 -ww rust-template.1
# Validateman --warnings rust-templateBuild Failures
Section titled “Build Failures”# Clean buildcargo cleancargo build
# Check build.rs outputcargo build -vv 2>&1 | grep "build script"