# Sphinx Integration

Cyclopts provides builtin Sphinx support.

## Quick Start

1. Add the extension to your Sphinx configuration (`docs/conf.py`):

       extensions = [
           'cyclopts.sphinx_ext',  # Add this line
           # ... your other extensions
       ]

2. Use the directive in your RST files:

       .. cyclopts:: mypackage.cli:app

## Directive Usage

### Basic Syntax

The `cyclopts` directive accepts a module path to your Cyclopts `App` object:

    .. cyclopts:: mypackage.cli:app

### Module Path Formats

The directive accepts two module path formats:

1. Explicit format (`module.path:app_name`):

       .. cyclopts:: mypackage.cli:app
       .. cyclopts:: myapp.commands:main_app
       .. cyclopts:: src.cli:cli

   This explicitly specifies which `App` object to document.

2. Automatic discovery (`module.path`):

       .. cyclopts:: mypackage.cli
       .. cyclopts:: myapp.main

   The extension will search the module for an `App` instance, looking for common names like `app`, `cli`, or `main`.

## Directive Options

The directive supports several options to customize the generated documentation:

### `:heading-level:` - Heading Level

Set the starting heading level for the generated documentation (1-6, default: 2):

    .. cyclopts:: mypackage.cli:app
       :heading-level: 3

This is useful when you need to adjust the heading hierarchy. The default of 2 works well for most cases where the directive is placed under a page title.

### `:max-heading-level:` - Maximum Heading Level

Set the maximum heading level to use (1-6, default: 6):

    .. cyclopts:: mypackage.cli:app
       :max-heading-level: 4

Headings deeper than this level will be capped at this value. This is useful for deeply nested command hierarchies where you want to prevent headings from becoming too small.

### `:no-recursive:` - Exclude Subcommands

Disable recursive documentation of subcommands (by default, subcommands are included):

    .. cyclopts:: mypackage.cli:app
       :no-recursive:

When this flag is present, only the top-level commands are documented.

### `:include-hidden:` - Show Hidden Commands

Include commands marked with `show=False` in the documentation:

    .. cyclopts:: mypackage.cli:app
       :include-hidden: true

By default, hidden commands are not included in the generated documentation.

### `:flatten-commands:` - Generate Flat Command Hierarchy

Generate all commands at the same heading level instead of nested hierarchy:

    .. cyclopts:: mypackage.cli:app
       :flatten-commands:

This creates distinct, equally-weighted headings for each command and subcommand, making them easier to reference and navigate in the documentation. Without this option, subcommands are nested with incrementing heading levels.

### `:code-block-title:` - Render Titles as Inline Code

Render command titles with inline code formatting instead of plain text:

    .. cyclopts:: mypackage.cli:app
       :code-block-title:

When this flag is present, command titles are rendered with monospace formatting, which can be useful for certain documentation themes or to make command names stand out visually.

### `:commands:` - Filter Specific Commands

Document only specific commands from your CLI application:

    .. cyclopts:: mypackage.cli:app
       :commands: init, build, deploy

This will only document the specified commands. You can also use nested command paths with dot notation:

    .. cyclopts:: mypackage.cli:app
       :commands: db.migrate, db.backup, api

- `db.migrate` - Documents only the `migrate` subcommand under `db`

- `db.backup` - Documents only the `backup` subcommand under `db`

- `api` - Documents the `api` command and all its subcommands

You can use either underscore or dash notation in command names - they will be normalized automatically.

### `:exclude-commands:` - Exclude Specific Commands

Exclude specific commands from the documentation:

    .. cyclopts:: mypackage.cli:app
       :exclude-commands: debug, internal-test

This is useful for hiding internal or debug commands from user-facing documentation. Like `:commands:`, this also supports nested command paths with dot notation.

### `:skip-preamble:` - Skip Description and Usage

Skip the description and usage sections for the target command when filtering to a single command:

    .. cyclopts:: mypackage.cli:app
       :commands: deploy
       :skip-preamble:

When you filter to a single command using `:commands:` and provide your own section heading in the RST, you may not want the directive to generate the command's description and usage block. Adding `:skip-preamble:` suppresses these sections while still generating the command's parameters and subcommands.

This is useful when you want to write your own introduction for a command section:

    Deployment
    ==========

    Deploy your application to production with these commands.

    .. cyclopts:: mypackage.cli:app
       :commands: deploy
       :skip-preamble:

Without `:skip-preamble:`, the output would include both your introduction and the command's docstring description, which can be redundant.

### `:usage-name:` - Override the Command Shown in Usage Lines

Replace the app name shown in `Usage:` lines of the generated documentation with a custom invocation string:

    .. cyclopts:: mypackage.cli:app
       :usage-name: uv run cli

This is useful when the documented invocation differs from the app's configured name. For example, an `App(name="cli", ...)` installed as a project entry point might typically be invoked as `uv run cli`; setting `:usage-name: uv run cli` renders that in every `Usage:` block while section headings, anchors, and the table of contents continue to reference the plain `cli` name.

### Automatic Reference Labels

The Sphinx directive automatically generates RST reference labels for all commands, enabling cross-referencing throughout your documentation. The anchor format is `cyclopts-{app-name}-{command-path}`, which prevents naming conflicts when documenting multiple CLIs.

For example: - Root application: `cyclopts-myapp` - Subcommand: `cyclopts-myapp-deploy` - Nested subcommand: `cyclopts-myapp-deploy-production`

You can reference these commands elsewhere in your documentation using `:ref:`cyclopts-myapp-deploy``.

## Complete Example

Here's a complete example showing a CLI application and its Sphinx documentation:

### CLI Application (`myapp/cli.py`):

    from pathlib import Path
    from typing import Optional
    from cyclopts import App

    app = App(
        name="myapp",
        help="My awesome CLI application",
        version="1.0.0"
    )

    @app.command
    def init(path: Path = Path("."), template: str = "default"):
        """Initialize a new project.

        Parameters
        ----------
        path : Path
            Directory where the project will be created
        template : str
            Project template to use
        """
        print(f"Initializing project at {path}")

    @app.command
    def build(source: Path, output: Optional[Path] = None, *, minify: bool = False):
        """Build the project.

        Parameters
        ----------
        source : Path
            Source directory
        output : Path, optional
            Output directory (defaults to source/dist)
        minify : bool
            Minify the output files
        """
        output = output or source / "dist"
        print(f"Building from {source} to {output}")

    if __name__ == "__main__":
        app()

### Sphinx Configuration (`docs/conf.py`):

    import sys
    from pathlib import Path

    # Add your package to the path
    sys.path.insert(0, str(Path(__file__).parent.parent))

    # Extensions
    extensions = [
        'cyclopts.sphinx_ext',
        'sphinx.ext.autodoc',  # For API docs
        'sphinx.ext.napoleon',  # For NumPy-style docstrings
    ]

    # Project info
    project = 'MyApp'
    author = 'Your Name'
    version = '1.0.0'

    # HTML theme
    html_theme = 'sphinx_rtd_theme'

### Documentation File (`docs/cli.rst`):

    CLI Reference
    =============

    This section documents all available CLI commands.

    .. cyclopts:: myapp.cli:app

    The above directive will automatically generate documentation for all
    commands, including their parameters, types, defaults, and help text.

## Advanced Usage

### Using Distinct Command Headings

When you want each command to have its own distinct heading for better navigation and referencing:

    CLI Command Reference
    =====================

    .. cyclopts:: myapp.cli:app
       :flatten-commands:
       :code-block-title:

    This generates:

    - All commands at the same heading level (not nested)
    - Command titles with monospace formatting
    - Automatic reference labels for cross-linking

    You can then reference specific commands:

    See :ref:`cyclopts-myapp-deploy` for deployment options.
    The :ref:`cyclopts-myapp-init` command sets up your project.

### Selective Command Documentation

Split your CLI documentation across multiple sections or pages:

    Database Commands
    =================

    The following commands manage database operations:

    .. cyclopts:: myapp.cli:app
       :commands: db

    API Management
    ==============

    Commands for controlling the API server:

    .. cyclopts:: myapp.cli:app
       :commands: api

    Development Tools
    =================

    Utilities for development (excluding internal debug commands):

    .. cyclopts:: myapp.cli:app
       :commands: dev
       :exclude-commands: dev.debug, dev.internal

This approach allows you to:

- Organize large CLI applications into logical sections

- Document different command groups on separate pages

- Exclude internal or debug commands from user documentation

- Create targeted documentation for different audiences

## Output Formats

While the Sphinx directive uses RST internally, you can also generate documentation programmatically in multiple formats:

    from myapp.cli import app

    # Generate reStructuredText
    rst_docs = app.generate_docs(output_format="rst")

    # Generate Markdown
    md_docs = app.generate_docs(output_format="markdown")

    # Generate HTML
    html_docs = app.generate_docs(output_format="html")

This is useful for generating documentation outside of Sphinx, such as for GitHub README files or other documentation systems.

## See Also

- Help - Customizing help output

- Commands - Creating commands and subcommands

- Parameters - Parameter types and validation

- Sphinx Documentation - Official Sphinx documentation