Metadata-Version: 2.4
Name: opdoc
Version: 0.1.0
Summary: Opinionated, self-contained pdoc documentation sites
Home-page: https://gitlab.com/meehai/opdoc
License: MIT
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE.TXT
Requires-Dist: pdoc==16.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.4; extra == "dev"
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# opdoc

Opinionated, self-contained [pdoc](https://pdoc.dev/) documentation sites. One command turns a
project's `docs/` directory plus its `README.md` into a themed static site with prose pages, API
reference, client-side search, and no config file.

```bash
opdoc docs/ public
```

`DOCS` is required; `OUT` defaults to `<project-root>/public`. The project root is the parent of
`DOCS`, so `opdoc docs/` works from a normal checkout.

## What a project supplies

```
project/
├── README.md                    home page (rendered as guide.html)
├── docs/
│   ├── custom.css               optional project CSS, appended after opdoc's base style
│   ├── source/**/*.md           prose pages; the directory tree is the "Pages" sidebar
│   └── scripts/*.py             optional build-time page generators
└── <packages>/                  auto-detected API roots
```

That is the whole contract. Theme, template, search, link rewriting, and the pdoc pin live in
opdoc.

## API pages

Without flags, opdoc documents every top-level package directory (a directory with `__init__.py`),
skipping `docs/`, `test/`, `examples/`, `pkg/`, `build/`, `dist/`, and `public/`. Each package's
re-exports are blanked in memory by default, so a class is documented once on its own module page.

For a `src/` layout, namespace packages, or a subset of packages, pass `--api-package` and the
matching import roots:

```bash
opdoc docs/ public \
  --api-package src/robolib \
  --api-package src/robosim \
  --import-path src \
  --import-path .
```

`--keep-reexports` leaves `__all__` alone when a package landing page should show its re-exports.

## Scripts

Every non-underscore `docs/scripts/*.py` is imported before `docs/source` is scanned. It must
define:

```python
def generate(site):
    text, _missing = build_the_page()
    site.write_page("3. Reference/generated.md", text)
```

`site.write_page(relative_path, text)` writes a markdown page below `docs/source`; the normal scan
then renders it to HTML. `site.root`, `site.docs`, and `site.out` are absolute paths. Scripts run
in filename order. `_`-prefixed files are helpers and are not run.

Scripts can import project code: `--import-path` entries are already on `sys.path` and in
`PYTHONPATH`. The scripts directory is on `sys.path` too, so a script may `import _helper` from a
sibling `_`-prefixed file.

## Pages menu

`docs/source/` is the sidebar:

- every `*.md` is a page; the title is its first `# ` heading (fallback: file name);
- a directory is a collapsible group; `index.md` makes the group itself a page;
- a leading number sorts first and numerically (`1. Examples`, `2. Architecture`);
- `_`-prefixed files/dirs are drafts; a top-level `README.md` is ignored (the repo README is home);
- names that slugify to the same module are an error.

Links in `README.md` and pages stay repo-relative. opdoc rewrites `*.md` links to the generated
pages, copies referenced images, and sends other repo paths to GitLab blob/tree URLs. Set
`--repo-slug owner/project` and `--repo-branch branch` when the git remote does not describe the
published repo (for example, a vendored checkout).

## Vendored sites

`--vendored NAME` adds `vendored/NAME/index.html` to the sidebar. It does **not** build that site;
an orchestrating project script builds each `pkg/NAME/docs` into `OUT/vendored/NAME/` with the same
tool. This keeps every site self-contained and avoids module collisions between projects.

## Install

```bash
pip install opdoc
```

opdoc pins the pdoc version it is tested against (`pdoc==16.0.0`) because it drives pdoc's render
API directly. Python 3.12+.

For development:

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest test/
python -m opdoc docs/ public
```

## Tests

- `test/unit/` exercises the pure helpers (slugging, ordering, source scanning, script loading,
  path guards).
- `test/integration/` builds a real fixture site with pdoc and checks the home page, API pages,
  generated script page, sidebar, rewritten links, assets, and CSS.
