Metadata-Version: 2.4
Name: nadoc
Version: 0.1.2
Summary: A simple static documentation generator for OpenAPI 3.1 specs
Author-email: Ibudidi <ibudidi@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/ibudidi/nadoc
Project-URL: Repository, https://github.com/ibudidi/nadoc
Project-URL: Issues, https://github.com/ibudidi/nadoc/issues
Project-URL: Changelog, https://github.com/ibudidi/nadoc/blob/main/CHANGELOG.md
Keywords: openapi,documentation,static-site,api
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Documentation
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Jinja2<4,>=3.1
Requires-Dist: markdown-it-py<5,>=3
Requires-Dist: Pygments<3,>=2.19
Requires-Dist: PyYAML<7,>=6
Provides-Extra: dev
Requires-Dist: build<2,>=1; extra == "dev"
Requires-Dist: pip-audit<3,>=2.7; extra == "dev"
Requires-Dist: pyright<2,>=1.1; extra == "dev"
Requires-Dist: ruff<1,>=0.9; extra == "dev"
Requires-Dist: setuptools>=83; extra == "dev"
Requires-Dist: twine<7,>=6; extra == "dev"
Provides-Extra: fonts
Requires-Dist: fonttools[woff]<5,>=4.53; extra == "fonts"
Dynamic: license-file

# Nadoc

Deterministic static documentation for OpenAPI.

Nadoc converts an OpenAPI 3.1 document and an optional OpenAPI Overlay 1.x document into a self-contained,
server-rendered API documentation site. CSS, JavaScript, and language icons are embedded in the generated HTML;
Python is only required at generation time.

> Nadoc 0.1.2 is a stable release for the documented renderer profile. Strict mode rejects known unsupported
> semantics rather than silently omitting them. See the compatibility reference for the supported scope.

## Requirements

- Python 3.10 or newer
- An OpenAPI 3.0 or 3.1 YAML or JSON document

## Install

For an isolated command-line installation from PyPI:

```bash
pipx install nadoc
```

Alternatively, install Nadoc into the active Python environment:

```bash
python3 -m pip install nadoc
```

From this source checkout:

```bash
python3 -m pip install .
```

## Quick start

```bash
nadoc openapi.yaml --output-dir api-docs
```

Open `api-docs/index.html` in a browser. The generated HTML embeds Nadoc's CSS, JavaScript, language icons, and Latin
subsets of Inter and JetBrains Mono, so viewing it does not require network resources. Run `nadoc --help` for all command-line options.

Nadoc automatically bundles relative-file `$ref` values in memory before applying overlays and rendering. To write the
standalone bundled document without rendering documentation, use:

```bash
nadoc bundle openapi/app.yaml --output openapi/bundled.yaml
```

Referenced paths are resolved relative to the document containing each `$ref`. YAML and JSON-formatted documents and
JSON Pointer fragments are supported. Network references are rejected and are never fetched.

## Configuration

Apply an optional overlay:

```bash
nadoc openapi.yaml \
  --overlay documentation-overlay.yaml \
  --output-dir api-docs
```

The HTML shell is minified by default; pass `--no-minify` (or `output.minify: false`) to keep the indented layout.
Embedded code and assets are never altered by minification. To keep the single file small, Nadoc ships Latin-subset
fonts, draws repeated icons from CSS masks instead of inline SVG, and compacts syntax-highlighted samples.

Customize the generated theme with a versioned Nadoc configuration:

```yaml
# nadoc.yaml
version: 1
input:
  spec: ./openapi.yaml
  overlay: ./overlay.yaml
  strict: true
site:
  title: Acme API
  product_name: Developer Platform
  language: en
theme:
  default: system
  preset: night-owl
  fonts:
    sans: Arial
    mono: Menlo
  colors:
    primary: "#2563eb"
code_samples:
  languages: [curl, python, javascript]
output:
  directory: ./api-docs
  html_file: index.html
  spec_file: openapi.yaml
  emit_spec: true
  embed_fonts: false
  minify: true
  dynamic_render: false
```

```bash
nadoc --config nadoc.yaml
```

Config version 1 supports `input.spec`, `input.overlay`, `input.strict`, `site.title`, `site.product_name`,
`site.language`, `theme.default`, `theme.preset`, `theme.fonts.sans`, `theme.fonts.mono`,
`theme.fonts.stylesheet`, `theme.colors.primary`, `code_samples.languages`, `output.directory`,
`output.html_file`, `output.spec_file`, `output.emit_spec`, `output.embed_fonts`, `output.minify`, and
`output.dynamic_render`. Relative input and output paths are resolved from the directory containing
the config file, so `nadoc --config nadoc.yaml` is independent of the current working directory.

`code_samples.languages` controls which request examples Nadoc generates and their order after authored `x-codeSamples`. Supported values are
`curl`, `python`, `javascript`, `node`, `go`, `java`, `php`, and `csharp`. All are generated by default for backward
compatibility. Use an empty list (`languages: []`) to disable generated examples; authored OpenAPI `x-codeSamples`
remain available.

The default display mode may be `system`, `light`, or `dark`. Presets include the dark themes `atom-one-dark`,
`dracula`, `night-owl`, `catppuccin-dark`, and `ayu-dark`, plus the light themes `atom-one-light`,
`bracket-light-pro`, `bluloco-light`, `catppuccin-light`, and `ayu-light`. The Atom One, Catppuccin, and Ayu presets are paired:
either variant styles both display modes, while the preset name selects the initial mode. When
`theme.default` is omitted, a preset selects its native light or dark mode. The theme toggle remains available and
uses Nadoc's neutral palette for the opposite mode except when a paired Atom One, Catppuccin, or Ayu preset is selected.

The primary color must use `#RRGGBB` notation. It overrides a preset's primary and accent colors and Nadoc derives
appropriate light and dark brand shades from it. Elevation shadows are always neutral grey/black and never inherit
the primary color, so unusual or red brand colors do not tint cards and panels.
The header brand mark uses the first non-whitespace character of the configured title, falling back to the OpenAPI
`info.title`.

Explicit command-line or Python API values override config values, which override Nadoc defaults. Boolean CLI
options support both forms, such as `--minify`/`--no-minify`, `--strict`/`--no-strict`,
`--emit-spec`/`--no-emit-spec`, `--embed-fonts`/`--no-embed-fonts`, and
`--dynamic-render`/`--no-dynamic-render`. Output file settings accept file names
only; place them using `output.directory`.
Other sections from the proposed v1 schema are reserved for future releases and are rejected rather than silently
ignored.

Dynamic rendering compresses operation bodies into per-tag chunks and inflates a chunk when one of its operations is
first opened. The decompressed chunk is cached while individual operation bodies are inserted only when requested.
It substantially reduces raw file size, initial DOM size, parse time, and memory use for large specifications. It
requires JavaScript and a modern browser with `DecompressionStream` support, and it cannot be combined with a custom
`--js` asset. Static rendering remains the default and preserves the no-JavaScript documentation baseline. Because
the dynamic payload is already compressed, applying gzip or Brotli to the complete HTML may produce a larger transfer
than compressing the repetitive static HTML; choose dynamic rendering for raw artifact and browser-runtime costs.

Generated files:

```text
api-docs/
├── index.html
└── openapi.yaml
```

Use custom progressive-enhancement assets with `--css` and `--js`. The default stylesheet exposes `--font-sans` and
`--font-mono` on `:root`. Set `theme.fonts.sans` and `theme.fonts.mono` to select preferred font families. Set
`output.embed_fonts: false` or pass `--no-embed-fonts` to omit the bundled font data and use system fonts or fonts loaded
from an optional HTTPS `theme.fonts.stylesheet`. For example, a Google Fonts CSS URL makes the generated page depend on
network access. Use `--check` to avoid writing and return exit code `1` when generated files are missing or stale. Input
and validation errors return exit code `2`.

```yaml
theme:
  fonts:
    sans: Roboto
    mono: Roboto Mono
    stylesheet: "https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap"
output:
  embed_fonts: false
```

Nadoc can also be used from Python:

```python
from nadoc import render

result = render(
    "openapi.yaml",
    overlay="documentation-overlay.yaml",
    config="nadoc.yaml",
    output_dir="api-docs",
)
print(result.html_path)
```

## Supported scope

Nadoc's versioned renderer profile is `nadoc-oas31-profile-v1`. It supports conventional path operations and top-level
webhook operations, parameters, request and response bodies, examples, servers and variables, tags, security schemes
and requirements, response headers and links, `x-codeSamples`, and a substantial documentation-focused subset of JSON
Schema 2020-12. Local references are consumed for schemas, parameters, request bodies, responses, headers, examples,
links, and root path items. Callback names are rendered as metadata; callback expressions and nested callback
operations are not expanded.

Schema composition and conditionals are presented as distinct branches rather than flattened. Nadoc also renders
common constraints and annotations and generates bounded, deterministic example values. These are documentation
features: Nadoc does not evaluate schema validity or claim that generated examples satisfy every constraint.

Network references, discriminator behavior, dynamic reference scope, callback operation expansion,
request execution, and formal validation remain outside the profile. Nadoc never fetches references or external
examples. Emitting a merged YAML document preserves input data but does not imply that every field has an HTML
representation. See the
[compatibility reference](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md) for the detailed supported
profile and explicit boundaries.

Nadoc natively targets OpenAPI 3.1 and accepts semantic versions in the `3.1.x` series. OpenAPI `3.0.x` documents are
rendered through a compatibility profile and produce one `OAS30_COMPAT` warning. The compatibility layer interprets
3.0 Schema Object `nullable` and boolean exclusive-bound semantics for documentation without changing the emitted
document. Nadoc rejects prerelease versions and versions outside the 3.0 and 3.1 series. `paths` may be omitted, but must be an object
when present. Nadoc's compatibility diagnostics are separate from formal OpenAPI
validation; the current release does not claim to validate every OpenAPI or JSON Schema constraint. In non-strict mode,
`render()` returns semantic-omission diagnostics in `RenderResult.diagnostics`; strict mode promotes them to errors.
The CLI prints non-strict diagnostics as `severity: CODE at location: message`. Compatibility/input failures exit `2`,
stale `--check` output exits `1`, and successful rendering exits `0`. For formal validation in CI, run a dedicated
OpenAPI 3.1 validator before Nadoc; Nadoc intentionally does not bundle or prescribe one.

## Generated site behavior

Generated pages include embedded styling, syntax-highlighted examples, theme selection, sidebar search, keyboard-aware
tabs, copy controls, server selection, language preference, mobile navigation, and a no-JavaScript documentation
baseline. Without JavaScript, operation details, all response and code panels, and mobile navigation remain readable;
controls that require JavaScript are hidden. Nadoc escapes document values and renders Markdown with raw HTML disabled.
By default, generated pages embed Inter, JetBrains Mono, CSS, JavaScript, and language icons, so they do not load
resources from the network. Configuring `theme.fonts.stylesheet` explicitly opts into that external request.

## Contributing

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, utility commands, testing,
and pull-request requirements. Compatibility changes must also update
[COMPATIBILITY.md](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md). Report defects or request features in the
[issue tracker](https://github.com/ibudidi/nadoc/issues).

Nadoc is available under the [MIT License](LICENSE).
