# API Reference Source: https://gp-sphinx.git-pull.com/api/ # API Reference Public API for building Sphinx configurations and source link resolvers. For shared defaults and configuration options, see {doc}`configuration`. ## merge_sphinx_config ```{eval-rst} .. autofunction:: gp_sphinx.config.merge_sphinx_config ``` When `docs_url` is provided, `merge_sphinx_config()` also auto-derives the `ogp_*` and `sitemap_*` keys consumed by the SEO extensions (`sphinx_gp_opengraph`, `sphinx_gp_sitemap`). See {ref}`from-docs_url` for the full mapping. ## make_linkcode_resolve ```{eval-rst} .. autofunction:: gp_sphinx.config.make_linkcode_resolve ``` ### Wiring into conf.py Pass the resolver to {py:func}`~gp_sphinx.config.merge_sphinx_config` via `**overrides`. {py:mod}`sphinx:sphinx.ext.linkcode` is auto-appended to extensions when `linkcode_resolve` is provided: ```python import my_project from gp_sphinx.config import make_linkcode_resolve, merge_sphinx_config conf = merge_sphinx_config( project="my-project", version=my_project.__version__, copyright="2026, My Name", source_repository="https://github.com/my-org/my-project/", linkcode_resolve=make_linkcode_resolve( my_project, "https://github.com/my-org/my-project", ), ) globals().update(conf) ``` ## deep_merge ```{eval-rst} .. autofunction:: gp_sphinx.config.deep_merge ``` ## setup ```{eval-rst} .. autofunction:: gp_sphinx.config.setup ``` --- # Architecture Source: https://gp-sphinx.git-pull.com/architecture/ (architecture)= # Architecture Workspace packages organized in tiers. Lower layers never depend on higher ones — autodoc extensions consume shared infrastructure, and the presentation layer wires everything together for downstream projects. The sidebar groups these packages into navigation buckets (Domain Packages, UX, Utils, Internal) — a reader-facing grouping that is orthogonal to the dependency-ordered tier map below. ## Tier 1: Shared infrastructure The rendering pipeline that every autodoc extension consumes: ::::{grid} 1 1 3 3 :gutter: 2 :::{grid-item-card} sphinx-ux-badges :link: packages/sphinx-ux-badges/index :link-type: doc Badge primitives, colour palette, and CSS infrastructure. All badge colours live in one place (`SAB.*` constants). ::: :::{grid-item-card} sphinx-ux-autodoc-layout :link: packages/sphinx-ux-autodoc-layout/index :link-type: doc Structural presenter for `api-*` entry components. Parameter folding, managed signatures, card regions. ::: :::{grid-item-card} sphinx-autodoc-typehints-gp :link: packages/sphinx-autodoc-typehints-gp/index :link-type: doc Annotation normalization and type rendering. Replaces `sphinx-autodoc-typehints` + `sphinx.ext.napoleon`. ::: :::: ## Tier 2: Autodoc extensions Domain-specific [autodoc extensions](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html) that consume Tier 1 and add project-specific rendering logic. Each ships directives that generate documentation from a particular source-construct family: ::::{grid} 1 1 2 3 :gutter: 2 :::{grid-item-card} sphinx-autodoc-api-style :link: packages/sphinx-autodoc-api-style/index :link-type: doc **Subject**: standard Python. **Directives**: `autofunction`, `autoclass`, `automodule`. ::: :::{grid-item-card} sphinx-autodoc-argparse :link: packages/sphinx-autodoc-argparse/index :link-type: doc **Subject**: argparse parsers — programs, options, subcommands, positionals. **Directives**: `argparse` (custom `argparse` domain). ::: :::{grid-item-card} sphinx-autodoc-docutils :link: packages/sphinx-autodoc-docutils/index :link-type: doc **Subject**: docutils directives and roles. **Directives**: `autodirective`, `autorole`. ::: :::{grid-item-card} sphinx-autodoc-fastmcp :link: packages/sphinx-autodoc-fastmcp/index :link-type: doc **Subject**: FastMCP tools, prompts, resources. **Directives**: `fastmcp-tool`, `fastmcp-tool-summary`. ::: :::{grid-item-card} sphinx-autodoc-pytest-fixtures :link: packages/sphinx-autodoc-pytest-fixtures/index :link-type: doc **Subject**: pytest fixtures (extends the `py` domain). **Directives**: `autofixture`, `autofixtures`, `auto-pytest-plugin`. ::: :::{grid-item-card} sphinx-autodoc-sphinx :link: packages/sphinx-autodoc-sphinx/index :link-type: doc **Subject**: Sphinx config values. **Directives**: `autoconfigvalue`, `autoconfigvalues`. ::: :::: Each autodoc extension calls `app.setup_extension()` to auto-register its infrastructure dependencies — downstream projects only need to add the package to their `extensions` list. ## Tier 3: Theme and coordinator | Package | Role | |---------|------| | {doc}`gp-sphinx ` | Coordinator. `merge_sphinx_config()` wires up the full stack. | | {doc}`sphinx-gp-theme ` | Furo-based theme with CSS variables and SPA navigation. | | {doc}`gp-furo-theme ` | Tailwind v4 port of upstream Furo for git-pull projects. | | {doc}`sphinx-fonts ` | IBM Plex via Fontsource — preloaded web fonts. | ## Build tooling Cross-cutting build utilities that operate outside the docs-build runtime — one is a [PEP 517](https://peps.python.org/pep-0517/) build backend invoked when wheels are produced; the other is an opt-in extension that drives the Vite watcher during `sphinx-autobuild`. Both let theme authors keep build artefacts (`static/styles/*.css`, `static/scripts/*.js`) out of VCS while still shipping working wheels and seamless live-reload during authoring. ::::{grid} 1 1 2 2 :gutter: 2 :::{grid-item-card} sphinx-vite-builder :link: packages/sphinx-vite-builder/index :link-type: doc [PEP 517](https://peps.python.org/pep-0517/) build backend (or hatchling build hook via `[tool.hatch.build.hooks.vite]`) that runs `pnpm exec vite build` before delegating wheel/sdist construction to hatchling. Also a Sphinx extension that auto-orchestrates `vite build --watch` during `sphinx-autobuild` and one-shot `vite build` during plain `sphinx-build`. Source builds error loudly without pnpm/Node; wheels ship turn-key. **Publishable for use outside this workspace** — any vite + Sphinx project can adopt either activation path without depending on the gp-sphinx coordinator. ::: :::: ## How the tiers connect Every autodoc extension shares the same badge palette, the same componentized HTML output structure, and the same type annotation pipeline — so [Python APIs](packages/sphinx-autodoc-api-style/index.md), [pytest fixtures](packages/sphinx-autodoc-pytest-fixtures/index.md), [Sphinx config values](packages/sphinx-autodoc-sphinx/index.md), [docutils directives](packages/sphinx-autodoc-docutils/index.md), and [FastMCP tools](packages/sphinx-autodoc-fastmcp/index.md) all look like they belong together. This is the **one autodoc design system** principle: a change to the shared infrastructure propagates instantly and consistently across every autodoc extension in the workspace. --- # Configuration Source: https://gp-sphinx.git-pull.com/configuration/ (configuration)= # Configuration Reference for {py:func}`gp_sphinx.config.merge_sphinx_config` and the shared defaults it applies. ## Integration pattern ```python from gp_sphinx.config import merge_sphinx_config conf = merge_sphinx_config( project="my-project", version="1.2.3", copyright="2026, Your Name", source_repository="https://github.com/your-org/my-project/", ) globals().update(conf) ``` {py:func}`~gp_sphinx.config.merge_sphinx_config` returns a flat dictionary meant to be injected into the module namespace with `globals().update(conf)`. That is the conventional Sphinx integration point: Sphinx reads `conf.py` globals directly, and the returned mapping already includes the coordinator’s generated `setup(app)` hook. ## `merge_sphinx_config()` parameters All parameters are keyword-only. | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `project` | `str` | required | Project name assigned to `project` and used in derived metadata | | `version` | `str` | required | Version string assigned to both `version` and `release` | | `copyright` | `str` | required | Copyright string for Sphinx metadata | | `extensions` | `list[str] \| None` | `None` | Seed extension list; when omitted, uses `DEFAULT_EXTENSIONS` | | `extra_extensions` | `list[str] \| None` | `None` | Additional extensions appended after the base list is chosen | | `remove_extensions` | `list[str] \| None` | `None` | Extensions removed from the selected base list | | `theme_options` | `dict[str, Any] \| None` | `None` | Deep-merged into `DEFAULT_THEME_OPTIONS` after auto-populated source/logo values | | `source_repository` | `str \| None` | `None` | GitHub repository URL used for issue links, footer icon URLs, and theme source metadata | | `source_branch` | `str` | `"main"` | Source branch stored in `html_theme_options["source_branch"]` | | `light_logo` | `str \| None` | `None` | Light-mode logo path merged into theme options | | `dark_logo` | `str \| None` | `None` | Dark-mode logo path merged into theme options | | `docs_url` | `str \| None` | `None` | Canonical docs URL. When set, auto-derives `ogp_site_url`, `ogp_site_name`, `ogp_image` (for `sphinx_gp_opengraph`) and `site_url`, `sitemap_url_scheme` (for `sphinx_gp_sitemap`) — see {ref}`from-docs_url` | | `intersphinx_mapping` | `Mapping[str, tuple[str, str \| None]] \| None` | `None` | Mapping assigned to `intersphinx_mapping` when provided | | `**overrides` | `Any` | none | Final escape hatch for any Sphinx config key; applied after all defaults and auto-computed values | ## Auto-computed values ### From `source_repository` | Key | Value | | --- | --- | | `issue_url_tpl` | `"{repo}/issues/{issue_id}"` | | `html_theme_options["source_repository"]` | repository URL | | `html_theme_options["footer_icons"][0]["url"]` | repository URL for the GitHub footer icon | (from-docs_url)= ### From `docs_url` | Key | Value | | --- | --- | | `ogp_site_url` | `docs_url` (trailing-slash normalized) | | `ogp_site_name` | `project` | | `ogp_image` | `"_static/img/icons/icon-192x192.png"` | | `site_url` | `docs_url` (trailing-slash normalized) | | `sitemap_url_scheme` | `"{link}"` | `sitemap_url_scheme` overrides upstream sphinx-sitemap's default of `"{lang}{version}{link}"` because git-pull.com sites deploy flat at the project root with no language or version path segment. Multilingual or version-pinned hosting can pass an explicit `sitemap_url_scheme` to `merge_sphinx_config()` to restore the prefixed scheme — `**overrides` is applied after auto-computation, so the explicit value wins. ### From `**overrides` If `linkcode_resolve` is present in `**overrides`, `merge_sphinx_config()` automatically appends {py:mod}`sphinx:sphinx.ext.linkcode` to `extensions` if it is not already present. ## Injected `setup(app)` The returned config includes a `setup(app)` function from {py:func}`gp_sphinx.config.setup`. It does two things: | Action | Effect | | --- | --- | | `app.add_js_file("js/spa-nav.js", loading_method="defer")` | Registers the bundled SPA navigation script from `sphinx-gp-theme` | | `app.connect("build-finished", remove_tabs_js)` | Removes `_static/tabs.js` after HTML builds as a `sphinx-inline-tabs` workaround | ## Always-set coordinator values These are injected even though they are not exposed as `DEFAULT_*` constants: | Key | Value | | --- | --- | | `master_doc` | `"index"` | | `release` | `version` | | `html_theme` | `DEFAULT_THEME` | | `html_theme_path` | `[]` | | `rediraffe_redirects` | `{}` | | `rediraffe_branch` | `"master~1"` | | `exclude_patterns` | `["_build"]` | | `setup` | {py:func}`gp_sphinx.config.setup` | ## Shared `DEFAULT_*` constants ### Extensions and source parsing | Constant | Value | | --- | --- | | `DEFAULT_EXTENSIONS` | `["sphinx.ext.autodoc", "sphinx_fonts", "sphinx.ext.intersphinx", "sphinx_autodoc_typehints_gp", "sphinx.ext.todo", "sphinx_inline_tabs", "sphinx_copybutton", "sphinx_gp_opengraph", "sphinx_gp_sitemap", "sphinxext.rediraffe", "sphinx_design", "myst_parser", "linkify_issues"]` | | `DEFAULT_SOURCE_SUFFIX` | `{".rst": "restructuredtext", ".md": "markdown"}` | | `DEFAULT_MYST_EXTENSIONS` | `["colon_fence", "substitution", "replacements", "strikethrough", "linkify"]` | | `DEFAULT_MYST_HEADING_ANCHORS` | `4` | | `DEFAULT_TEMPLATES_PATH` | `["_templates"]` | | `DEFAULT_HTML_STATIC_PATH` | `["_static"]` | ### Theme defaults | Constant | Value | | --- | --- | | `DEFAULT_THEME` | `"sphinx-gp-theme"` | | `DEFAULT_THEME_OPTIONS` | footer GitHub icon, `source_repository=""`, `source_branch="main"`, `source_directory="docs/"` | ### Font defaults | Constant | Value | | --- | --- | | `DEFAULT_SPHINX_FONTS` | IBM Plex Sans (400/500/600/700, normal+italic) and IBM Plex Mono (400, normal+italic) Fontsource definitions | | `DEFAULT_SPHINX_FONT_PRELOAD` | IBM Plex Sans 400 / 500 / 600 / 700 normal + 400 italic, IBM Plex Mono 400 / 700 normal | | `DEFAULT_SPHINX_FONT_FALLBACKS` | Metric-adjusted Arial and Courier fallback declarations | | `DEFAULT_SPHINX_FONT_CSS_VARIABLES` | `--font-stack`, `--font-stack--monospace`, `--font-stack--headings` | ### Syntax highlighting and copybutton | Constant | Value | | --- | --- | | `DEFAULT_PYGMENTS_STYLE` | `"monokai"` | | `DEFAULT_PYGMENTS_DARK_STYLE` | `"monokai"` | | `DEFAULT_COPYBUTTON_PROMPT_TEXT` | regex matching Python, shell, and IPython prompts | | `DEFAULT_COPYBUTTON_PROMPT_IS_REGEXP` | `True` | | `DEFAULT_COPYBUTTON_REMOVE_PROMPTS` | `True` | | `DEFAULT_COPYBUTTON_LINE_CONTINUATION_CHARACTER` | `"\\"` | ### Autodoc defaults | Constant | Value | | --- | --- | | `DEFAULT_AUTOCLASS_CONTENT` | `"class"` | | `DEFAULT_AUTODOC_MEMBER_ORDER` | `"bysource"` | | `DEFAULT_AUTODOC_CLASS_SIGNATURE` | `"separated"` | | `DEFAULT_AUTODOC_TYPEHINTS` | `"description"` | | `DEFAULT_TOC_OBJECT_ENTRIES_SHOW_PARENTS` | `"hide"` | | `DEFAULT_AUTODOC_OPTIONS` | `{"undoc-members": True, "members": True, "private-members": True, "show-inheritance": True, "member-order": "bysource"}` | ### Warning defaults | Constant | Value | | --- | --- | | `DEFAULT_SUPPRESS_WARNINGS` | `[]` | ## Parameter interactions - `extensions`, `extra_extensions`, and `remove_extensions` are applied in that order. - `theme_options` is deep-merged, so nested theme dictionaries can be overridden without replacing the whole structure. - `**overrides` runs last, so it can replace any default or auto-computed value. - The returned `setup(app)` hook survives `globals().update(conf)` intact because Sphinx reads it as a normal top-level `conf.py` function. --- # Gallery Source: https://gp-sphinx.git-pull.com/gallery/ (gallery)= # Gallery Every example on this page is **rendered live** from the same extensions and theme your project gets out of the box. Nothing is mocked — the output below is the real autodoc pipeline. --- ## Python API Badges, type hints, and card layout working together on standard Python domain directives. ```{py:module} gp_demo_api :no-index: ``` ### Functions ```{eval-rst} .. autofunction:: gp_demo_api.demo_function :noindex: ``` ```{eval-rst} .. autofunction:: gp_demo_api.demo_async_function :noindex: ``` ```{eval-rst} .. autofunction:: gp_demo_api.demo_deprecated_function :noindex: ``` ### Module data ```{eval-rst} .. autodata:: gp_demo_api.DEMO_CONSTANT :noindex: ``` ### Exceptions ```{eval-rst} .. autoexception:: gp_demo_api.DemoError :noindex: ``` ### Classes ```{eval-rst} .. autoclass:: gp_demo_api.DemoClass :members: :undoc-members: :noindex: ``` ### Abstract base classes ```{eval-rst} .. autoclass:: gp_demo_api.DemoAbstractBase :members: :noindex: ``` --- ## Layout regions and parameter folding Large parameter lists fold automatically. The class below has 13 parameters (above the default threshold of 10), so its field list is collapsed into a disclosure widget. ```{py:module} api_demo_layout :no-index: ``` ### Class with members (regions + fold) ```{eval-rst} .. autoclass:: api_demo_layout.LayoutDemo :members: :noindex: ``` ### Small function (no fold) ```{eval-rst} .. autofunction:: api_demo_layout.compact_function :noindex: ``` --- ## Badge palette The full badge system — types, modifiers, sizes, and variants — rendered by the real `build_badge` / `build_badge_group` / `build_toolbar` API: ```{gp-sphinx-badge-demo} ``` --- ## FastMCP tool cards Tool documentation with safety badges and parameter tables. ```{eval-rst} .. fastmcp-tool:: fastmcp_demo_tools.list_sessions :no-index: .. fastmcp-tool:: fastmcp_demo_tools.create_session :no-index: .. fastmcp-tool:: fastmcp_demo_tools.delete_session :no-index: ``` ### Parameter table ```{eval-rst} .. fastmcp-tool-input:: fastmcp_demo_tools.create_session ``` ### Tool summary ```{eval-rst} .. fastmcp-tool-summary:: ``` --- ## pytest fixtures ```{py:module} spf_demo_fixtures :no-index: ``` ### Fixture reference ```{eval-rst} .. autofixtures:: spf_demo_fixtures :no-index: ``` --- ## Sphinx config values ```{eval-rst} .. autoconfigvalues:: sphinx_config_demo :no-index: ``` --- ## docutils directives and roles ### Directives ```{eval-rst} .. autodirective:: docutils_demo.DemoBadgeDirective :no-index: ``` ### Roles ```{eval-rst} .. autorole:: docutils_demo.demo_badge_role :no-index: ``` --- # Changelog Source: https://gp-sphinx.git-pull.com/history/ (history)= ```{include} ../CHANGES ``` --- # gp-sphinx Source: https://gp-sphinx.git-pull.com/ (index)= # gp-sphinx Integrated autodoc design system for [git-pull](https://github.com/git-pull) Sphinx projects. ::::{grid} 1 1 2 3 :gutter: 2 2 3 3 :::{grid-item-card} What's New :link: whats-new :link-type: doc The unified autodoc design system — seven major advancements. ::: :::{grid-item-card} Gallery :link: gallery :link-type: doc Visual showcase of the autodoc design system in action. ::: :::{grid-item-card} Architecture :link: architecture :link-type: doc Split into common libraries, build utils, autodoc extensions, and UX. ::: :::{grid-item-card} Quickstart :link: quickstart :link-type: doc Install and get started in minutes. ::: :::{grid-item-card} Packages :link: packages/index :link-type: doc Coordinator, autodoc extensions, build utils, UX components, and theme. ::: :::{grid-item-card} Configuration :link: configuration :link-type: doc Parameter reference for {py:func}`~gp_sphinx.config.merge_sphinx_config` and shared defaults. ::: :::: ## Install ```console $ pip install gp-sphinx ``` ```console $ uv add gp-sphinx ``` ## At a glance Replace ~300 lines of duplicated `docs/conf.py` with ~10 lines: ```python from gp_sphinx.config import merge_sphinx_config conf = merge_sphinx_config( project="my-project", version="1.0.0", copyright="2026, Tony Narlock", source_repository="https://github.com/git-pull/my-project/", ) globals().update(conf) ``` ## What you get Out of the box, {py:func}`~gp_sphinx.config.merge_sphinx_config` activates: - **Unified badge system** — type and modifier badges for functions, classes, fixtures, tools - **Componentized layout** — card containers, parameter folding, managed signatures - **Clean type hints** — simplified annotations with cross-referenced links - **Autodoc extensions** — Python API, pytest fixtures, FastMCP tools, docutils, Sphinx config - **IBM Plex fonts** — professional typography with preloaded web fonts - **Dark mode** — full light/dark theming via CSS custom properties See the {doc}`gallery` to see these in action. ```{toctree} :hidden: whats-new gallery architecture quickstart configuration packages/index api project/index history GitHub ``` ```{cluster-toctree} autodoc :caption: Autodoc ``` ```{cluster-toctree} ux :caption: UX ``` ```{cluster-toctree} tokens :caption: Tokens ``` ```{cluster-toctree} theme-coordinator :caption: Theme & coordinator ``` ```{cluster-toctree} build-seo :caption: Build & SEO ``` --- # @gp-sphinx/furo-tokens Source: https://gp-sphinx.git-pull.com/packages/@gp-sphinx/furo-tokens/ (@gp-sphinx/furo-tokens)= # @gp-sphinx/furo-tokens ```{package-landing} @gp-sphinx/furo-tokens ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/gp-furo-theme/dependents/ (gp-furo-theme-dependents)= # Dependents ```{package-dependents} gp-furo-theme ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/gp-furo-theme/how-to/ (gp-furo-theme-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["gp_furo_theme"] html_theme = "gp-furo" ``` ## CSS authoring layout The asset pipeline lives in `packages/gp-furo-theme/web/`: ``` web/ ├── package.json # tailwindcss, @tailwindcss/vite, typescript ├── vite.config.ts # two rollup entries: scripts/furo, styles/furo-tw └── src/ ├── scripts/ │ ├── furo.ts # strict-typed port of upstream furo.js │ └── gumshoe.js # vendored; UMD→ESM surgery only └── styles/ ├── index.css # entry: @import "tailwindcss" + @plugin │ # + @custom-variant dark │ # + per-component imports └── components/ ├── base.css # typography, links, .visually-hidden, print ├── typography.css # article-class typography + :target ├── lists.css # ul/ol/dl + .field-list / .option-list ├── tables.css, footnotes.css, captions.css, ├── images.css, math.css, blocks.css ├── admonitions.css # 11 type variants + mask-image icons ├── code.css # inline + block + linenos + copybutton ├── api.css # autodoc signatures + version banners ├── search.css # results listing ├── scaffold.css # 3-col layout + responsive drawers ├── sidebar.css # toctree-checkbox toggle + brand ├── toc.css # scroll-spy active state ├── footer.css # bottom-of-page + related-pages └── extensions.css # sphinx-design / inline-tabs / copybutton ``` The 153 Furo CSS custom properties (light + dark) come from `@gp-sphinx/furo-tokens`'s Tailwind v4 plugin; component CSS references them via `var(--color-foreground-primary)` etc. so dark-mode swaps work at runtime via `body[data-theme="dark"]`. ## Visual fidelity Verified by `tests/visual/test_visual_regression.py`: 12 representative pages × 2 modes × 3 viewports = 72 baseline screenshots captured from the previously vendored SCSS pipeline. The current Tailwind output diffs at ~20% average against those baselines — driven mostly by minor margin/padding deltas that propagate through long scrolling pages. Per-page tightening to <0.5% is iterative follow-up work. Behavioral parity is verified by `tests/visual/test_furo_behaviors.py` (mobile sidebar drawer, skip-to-content focus; theme-toggle / scroll-spy / back-to-top documented and skipped pending a switch to mouse-wheel- synthesised scroll events — see test docstrings). ## Attribution Templates, scripts, and Python hooks are ported from upstream Furo at commit `b788b8a41aea7323b541975590a284f9f9db8f8e`. Furo is MIT-licensed by Pradyun Gedam; the full license text is reproduced at `packages/gp-furo-theme/LICENSE-FURO`. Each ported file carries a 1-line attribution header pointing at upstream. The CSS files (re-authored in pure Tailwind v4 from upstream's SCSS, file-by-file) carry the same attribution pointing at the upstream SCSS source they replicate. ```{package-reference} gp-furo-theme ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/gp-furo-theme) [Furo]: https://github.com/pradyunsg/furo [Vite]: https://vitejs.dev --- # gp-furo-theme Source: https://gp-sphinx.git-pull.com/packages/gp-furo-theme/ (gp-furo-theme)= # gp-furo-theme ```{package-landing} gp-furo-theme ``` --- # Signatures (live) Source: https://gp-sphinx.git-pull.com/packages/gp-furo-theme/signatures/ (gp-furo-theme-signatures)= # Signatures (live) ```{live-signature} gp-furo-theme ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/gp-sphinx/how-to/ (gp-sphinx-how-to)= # How to ## Downstream `conf.py` ```python from __future__ import annotations from gp_sphinx.config import merge_sphinx_config import my_project conf = merge_sphinx_config( project="my-project", version=my_project.__version__, copyright="2026, Your Name", source_repository="https://github.com/your-org/my-project/", docs_url="https://my-project.example.com/", intersphinx_mapping={ "py": ("https://docs.python.org/3", None), }, ) globals().update(conf) ``` ## What it injects - Shared extension defaults, theme defaults, fonts, MyST, napoleon, copybutton, and rediraffe settings. - Auto-computed `issue_url_tpl` and theme source-repository wiring from `source_repository`. - Auto-computed SEO values when `docs_url` is set: `ogp_site_url`, `ogp_site_name`, `ogp_image` for {doc}`/packages/sphinx-gp-opengraph/index`, plus `site_url` and `sitemap_url_scheme` for {doc}`/packages/sphinx-gp-sitemap/index`. See {ref}`from-docs_url` for the canonical mapping. - A `setup(app)` hook that registers `js/spa-nav.js` and removes `tabs.js` after HTML builds. - Support for appending {py:mod}`sphinx:sphinx.ext.linkcode` automatically when `linkcode_resolve` is supplied in `**overrides`. See {doc}`/configuration` for the complete parameter reference and every shared `DEFAULT_*` constant. ## SEO emission for free `sphinx_gp_opengraph` and `sphinx_gp_sitemap` are members of {py:data}`~gp_sphinx.defaults.DEFAULT_EXTENSIONS`, so every project that calls `merge_sphinx_config()` loads them automatically. Passing `docs_url=` is the only step required for default SEO emission — gp-sphinx fills in the upstream config keys both extensions need. Per-package details live on the {doc}`/packages/sphinx-gp-opengraph/index` and {doc}`/packages/sphinx-gp-sitemap/index` pages. :::{admonition} Live example This site is built with `gp-sphinx`, using the same integration pattern shown above. See [docs/conf.py](https://github.com/git-pull/gp-sphinx/blob/main/docs/conf.py) for the exact coordinator call. ::: ```{package-reference} gp-sphinx ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/gp-sphinx) · [PyPI](https://pypi.org/project/gp-sphinx/) --- # gp-sphinx Source: https://gp-sphinx.git-pull.com/packages/gp-sphinx/ (gp-sphinx)= # gp-sphinx ```{package-landing} gp-sphinx ``` --- # Packages Source: https://gp-sphinx.git-pull.com/packages/ # Packages The workspace ships independently-installable Sphinx packages organized by family. Each package has its own page; the {ref}`grid below ` auto-enumerates the full set as the workspace evolves. [`gp-sphinx`](gp-sphinx/index.md) is the umbrella entry point — its `merge_sphinx_config()` wires up the full stack for downstream projects in ~10 lines of `conf.py`. Every other package is opt-in and independently installable. ## Common libraries The rendering pipeline every autodoc extension consumes: - [`sphinx-ux-badges`](sphinx-ux-badges/index.md) — badge primitives and colour palette - [`sphinx-ux-autodoc-layout`](sphinx-ux-autodoc-layout/index.md) — structural presenter for `api-*` entry components - [`sphinx-autodoc-typehints-gp`](sphinx-autodoc-typehints-gp/index.md) — annotation normalization and type rendering - [`sphinx-fonts`](sphinx-fonts/index.md) — IBM Plex font preloading ## Autodoc extensions Domain-specific [autodoc extensions](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html) — each adds directives that generate documentation from a particular source-construct family (Python APIs, argparse parsers, pytest fixtures, etc.): - [`sphinx-autodoc-api-style`](sphinx-autodoc-api-style/index.md) — Python API rendering style - [`sphinx-autodoc-argparse`](sphinx-autodoc-argparse/index.md) — argparse parsers + subcommands - [`sphinx-autodoc-docutils`](sphinx-autodoc-docutils/index.md) — docutils directives + nodes - [`sphinx-autodoc-fastmcp`](sphinx-autodoc-fastmcp/index.md) — FastMCP tools, prompts, resources - [`sphinx-autodoc-pytest-fixtures`](sphinx-autodoc-pytest-fixtures/index.md) — pytest fixtures - [`sphinx-autodoc-sphinx`](sphinx-autodoc-sphinx/index.md) — Sphinx config values ## Build utils [PEP 517](https://peps.python.org/pep-0517/) backends and orchestration helpers for theme asset pipelines: - [`sphinx-vite-builder`](sphinx-vite-builder/index.md) — [PEP 517](https://peps.python.org/pep-0517/) backend + Sphinx extension that runs Vite via pnpm ## Theme and coordinator Shared Sphinx configuration and presentation assets: - [`gp-sphinx`](gp-sphinx/index.md) — umbrella coordinator (`merge_sphinx_config()`) - [`sphinx-gp-theme`](sphinx-gp-theme/index.md) — Furo child theme with the gp-sphinx default palette - [`gp-furo-theme`](gp-furo-theme/index.md) — Tailwind v4 port of upstream Furo for git-pull projects ## SEO and agent formats Meta-tag, crawlability, and LLM-friendly output extensions auto-loaded by `gp-sphinx` when `docs_url` is set: - [`sphinx-gp-opengraph`](sphinx-gp-opengraph/index.md) — Open Graph + Twitter Card meta tags - [`sphinx-gp-sitemap`](sphinx-gp-sitemap/index.md) — `sitemap.xml` for crawl indexing - [`sphinx-gp-llms`](sphinx-gp-llms/index.md) — `llms.txt`, `llms-full.txt`, `docs.json`, per-page `.md` twins ## Design philosophy Together, the common libraries provide **one autodoc design system**: every autodoc extension shares the same badge palette, the same componentized HTML output structure, and the same static type annotation pipeline — so Python APIs, pytest fixtures, Sphinx config values, docutils directives, and FastMCP tools all look like they belong together. (all-workspace-packages)= ## All workspace packages ```{workspace-package-grid} ``` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-api-style/examples/ (sphinx-autodoc-api-style-examples)= # Examples ## Live demos ```{py:module} gp_demo_api ``` ### Functions ```{eval-rst} .. autofunction:: gp_demo_api.demo_function ``` ```{eval-rst} .. autofunction:: gp_demo_api.demo_async_function ``` ```{eval-rst} .. autofunction:: gp_demo_api.demo_deprecated_function ``` ### Module data ```{eval-rst} .. autodata:: gp_demo_api.DEMO_CONSTANT ``` ### Exceptions ```{eval-rst} .. autoexception:: gp_demo_api.DemoError ``` ### Classes ```{eval-rst} .. autoclass:: gp_demo_api.DemoClass :members: :undoc-members: ``` ### Abstract base classes ```{eval-rst} .. autoclass:: gp_demo_api.DemoAbstractBase :members: ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-api-style/how-to/ (sphinx-autodoc-api-style-how-to)= # How to ## Features - **Type badges** (rightmost): `function`, `class`, `method`, `property`, `attribute`, `data`, `exception` — each with a distinct color - **Modifier badges** (left of type): `async`, `classmethod`, `staticmethod`, `abstract`, `final`, `deprecated` - **Card containers**: bordered cards with secondary-background headers - **Dark mode**: full light/dark theming via CSS custom properties - **Accessibility**: keyboard-focusable badges with tooltip popups - **Non-invasive**: hooks into `doctree-resolved` without replacing directives ## Downstream `conf.py` Add `sphinx_autodoc_api_style` to your Sphinx extensions. With `gp-sphinx`, use `extra_extensions`: ```python conf = merge_sphinx_config( project="my-project", version="1.0.0", copyright="2026, Your Name", source_repository="https://github.com/your-org/my-project/", extra_extensions=["sphinx_autodoc_api_style"], ) ``` Or without `merge_sphinx_config`: ```python extensions = ["sphinx_autodoc_api_style"] ``` `sphinx_autodoc_api_style` automatically registers `sphinx_ux_badges` and `sphinx_ux_autodoc_layout` via `app.setup_extension()`. You do not need to add them separately to your `extensions` list. ## CSS prefix All badge CSS classes use the `sab-` prefix from {doc}`/packages/sphinx-ux-badges/index`. Layout card classes (borders, headers, field-list rules) are local to this package and use `dl.py-*` and `.api-*` selectors. ```{package-reference} sphinx-autodoc-api-style ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-api-style) · [PyPI](https://pypi.org/project/sphinx-autodoc-api-style/) --- # sphinx-autodoc-api-style Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-api-style/ (sphinx-autodoc-api-style)= # sphinx-autodoc-api-style ```{package-landing} sphinx-autodoc-api-style ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-api-style/reference/ (sphinx-autodoc-api-style-reference)= # API Reference ## Badge reference All badge classes are drawn from the shared `sphinx_ux_badges.SAB` palette. This extension uses: | Object type | `SAB` constant | CSS class | |---|---|---| | `function` | `SAB.TYPE_FUNCTION` | `gp-sphinx-badge--type-function` | | `class` | `SAB.TYPE_CLASS` | `gp-sphinx-badge--type-class` | | `method` | `SAB.TYPE_METHOD` | `gp-sphinx-badge--type-method` | | `property` | `SAB.TYPE_PROPERTY` | `gp-sphinx-badge--type-property` | | `attribute` | `SAB.TYPE_ATTRIBUTE` | `gp-sphinx-badge--type-attribute` | | `data` | `SAB.TYPE_DATA` | `gp-sphinx-badge--type-data` | | `exception` | `SAB.TYPE_EXCEPTION` | `gp-sphinx-badge--type-exception` | | Modifier | `SAB` constant | CSS class | |---|---|---| | `async` | `SAB.MOD_ASYNC` | `gp-sphinx-badge--mod-async` | | `classmethod` | `SAB.MOD_CLASSMETHOD` | `gp-sphinx-badge--mod-classmethod` | | `staticmethod` | `SAB.MOD_STATICMETHOD` | `gp-sphinx-badge--mod-staticmethod` | | `abstract` | `SAB.MOD_ABSTRACT` | `gp-sphinx-badge--mod-abstract` | | `final` | `SAB.MOD_FINAL` | `gp-sphinx-badge--mod-final` | | `deprecated` | `SAB.STATE_DEPRECATED` | `gp-sphinx-badge--state-deprecated` | See {doc}`/packages/sphinx-ux-badges/index` for the full shared palette. --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-api-style/tutorial/ (sphinx-autodoc-api-style-tutorial)= # Tutorial ## Working usage examples No special directives are needed — existing `.. autofunction::`, `.. autoclass::`, `.. automodule::` directives automatically receive badges. Render one function: ````myst ```{eval-rst} .. autofunction:: my_project.api.demo_function ``` ```` Render one class and its members: ````myst ```{eval-rst} .. autoclass:: my_project.api.DemoClass :members: ``` ```` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/examples/ (sphinx-autodoc-argparse-examples)= # Examples ## Live demos ### Base parser rendering ```{argparse} :module: demo_cli :func: create_parser :prog: myapp ``` ### Subcommand rendering Drill into a single subcommand with `:path:`: ```{argparse} :module: demo_cli :func: create_parser :path: mysubcommand :prog: myapp ``` ### Inline roles The exemplar layer also registers live inline roles for CLI prose: {cli-command}`myapp`, {cli-option}`--verbose`, {cli-choice}`json`, {cli-metavar}`DIR`, and {cli-default}`text`. --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/how-to/ (sphinx-autodoc-argparse-how-to)= # How to ## Registered directives and roles ### Base `argparse` directive ```{eval-rst} .. autodirective:: sphinx_autodoc_argparse.directive.ArgparseDirective :no-index: ``` ### Exemplar override ```{eval-rst} .. autodirective:: sphinx_autodoc_argparse.exemplar.CleanArgParseDirective ``` ### CLI role callables ```{eval-rst} .. autoroles:: sphinx_autodoc_argparse.roles ``` ## Downstream usage snippets Use native MyST directives in Markdown: ````myst ```{argparse} :module: myproject.cli :func: create_parser :prog: myproject ``` ```` Or reStructuredText: ```rst .. argparse:: :module: myproject.cli :func: create_parser :prog: myproject ``` ```{package-reference} sphinx-autodoc-argparse ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-argparse) · [PyPI](https://pypi.org/project/sphinx-autodoc-argparse/) --- # sphinx-autodoc-argparse Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/ (sphinx-autodoc-argparse)= # sphinx-autodoc-argparse ```{package-landing} sphinx-autodoc-argparse ``` --- # Kitchen sink Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/kitchen-sink/ (sphinx-autodoc-argparse-kitchen-sink)= # Kitchen sink ```{package-kitchen-sink} sphinx-autodoc-argparse ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/reference/ (sphinx-autodoc-argparse-reference)= # API Reference ## Cross-reference roles Every `.. argparse::` block populates a dedicated `argparse` domain alongside the existing `std:cmdoption` entries. Use these roles to link to programs, options, subcommands, and positional arguments declared anywhere in the project: | Role | Resolves to | Example | |------|-------------|---------| | `:argparse:program:` | A top-level program | `` :argparse:program:`myapp` `` | | `:argparse:option:` | An optional flag, scoped by program | `` :argparse:option:`myapp --verbose` `` or `` :argparse:option:`myapp sync --force` `` | | `:argparse:subcommand:` | A subcommand under a parent program | `` :argparse:subcommand:`myapp sync` `` | | `:argparse:positional:` | A positional argument, scoped by program | `` :argparse:positional:`myapp FILE` `` | Whitespace-joined targets (`myapp sync --force`) are split on the final space to match the stored `(program, name)` tuple. Bare forms (`--verbose`) also resolve when only one registration matches, though the fully-qualified form is preferred for multi-program sites. ### Auto-generated indices Two domain indices are built into every project that loads the extension: - `argparse-programsindex` — alphabetised list of every registered program; link via `` :ref:`argparse-programsindex` ``. - `argparse-optionsindex` — options grouped by program, alphabetised within each group; link via `` :ref:`argparse-optionsindex` ``. ### Intersphinx compatibility The classic `:option:` / `std:cmdoption` emission is preserved — both roles resolve and both appear in `objects.inv`. Downstream consumers linking via intersphinx continue to work; new authoring inside projects using this extension can prefer the `:argparse:*` namespace for program-scoped clarity. ## Configuration values ### Base extension ```{eval-rst} .. autoconfigvalues:: sphinx_autodoc_argparse ``` ### Exemplar layer ```{eval-rst} .. autoconfigvalues:: sphinx_autodoc_argparse.exemplar ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-argparse/tutorial/ (sphinx-autodoc-argparse-tutorial)= # Tutorial ## Working usage examples ```python extensions = [ "sphinx_autodoc_argparse", "sphinx_autodoc_argparse.exemplar", ] argparse_examples_section_title = "Examples" argparse_reorder_usage_before_examples = True ``` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-docutils/examples/ (sphinx-autodoc-docutils-examples)= # Examples ## Live demos This page intentionally uses directive and role autodoc to document the documentation helpers themselves. If that feels a little recursive, that is the point: roles and directives should be documentable the same way fixtures are. ### Document one demo directive ```{eval-rst} .. autodirective:: docutils_demo.DemoBadgeDirective :no-index: ``` ### Document one demo role ```{eval-rst} .. autorole:: docutils_demo.demo_badge_role :no-index: ``` ### Bulk directives demo Renders all directive classes in a module at once: ```{eval-rst} .. autodirectives:: docutils_demo :no-index: ``` ### Bulk roles demo Renders all role callables in a module at once: ```{eval-rst} .. autoroles:: docutils_demo :no-index: ``` The extension itself registers directives, not docutils roles or Sphinx config values. The generated package reference below lists its registered surface from the live `setup()` calls. ```{package-reference} sphinx-autodoc-docutils ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-docutils) · [PyPI](https://pypi.org/project/sphinx-autodoc-docutils/) --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-docutils/how-to/ (sphinx-autodoc-docutils-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_autodoc_docutils"] ``` `sphinx_autodoc_docutils` automatically registers `sphinx_ux_badges`, `sphinx_ux_autodoc_layout`, and `sphinx_autodoc_typehints_gp` via `app.setup_extension()`. You do not need to add them separately to your `extensions` list. --- # sphinx-autodoc-docutils Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-docutils/ (sphinx-autodoc-docutils)= # sphinx-autodoc-docutils ```{package-landing} sphinx-autodoc-docutils ``` --- # Kitchen sink Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-docutils/kitchen-sink/ (sphinx-autodoc-docutils-kitchen-sink)= # Kitchen sink ```{package-kitchen-sink} sphinx-autodoc-docutils ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-docutils/tutorial/ (sphinx-autodoc-docutils-tutorial)= # Tutorial ## Working usage examples Use a single-object directive when you want one rendered reference entry: ````myst ```{eval-rst} .. autodirective:: my_project.docs_ext.MyDirective ``` ```` ````myst ```{eval-rst} .. autorole:: my_project.docs_roles.cli_option_role ``` ```` Use the bulk directives to render every directive or role a module registers: ````myst ```{eval-rst} .. autodirectives:: my_project.docs_ext ``` ```` ````myst ```{eval-rst} .. autoroles:: my_project.docs_roles ``` ```` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/examples/ (sphinx-autodoc-fastmcp-examples)= # Examples ## Live demos Use {tool}`list_sessions` for a linked badge, or {toolref}`delete_session` for a plain inline reference. ### Tool cards ```{eval-rst} .. fastmcp-tool:: fastmcp_demo_tools.list_sessions .. fastmcp-tool:: fastmcp_demo_tools.create_session .. fastmcp-tool:: fastmcp_demo_tools.delete_session ``` ### Parameter table ```{eval-rst} .. fastmcp-tool-input:: fastmcp_demo_tools.create_session ``` ### Tool summary ```{eval-rst} .. fastmcp-tool-summary:: ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/how-to/ (sphinx-autodoc-fastmcp-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_autodoc_fastmcp"] fastmcp_tool_modules = [ "my_project.docs.fastmcp_tools", ] fastmcp_area_map = { "fastmcp_tools": "api/tools", } fastmcp_collector_mode = "register" # Optional: point at a live FastMCP server instance to autodoc its prompts, # resources, and resource templates. Format is "module.path:attr_name". # Both an instance and a zero-arg factory callable are accepted. fastmcp_server_module = "my_project.server:mcp" ``` `sphinx_autodoc_fastmcp` automatically registers `sphinx_ux_badges`, `sphinx_ux_autodoc_layout`, and `sphinx_autodoc_typehints_gp` via `app.setup_extension()`. You do not need to add them separately to your `extensions` list. ## `fastmcp_server_module` Pointing the collector at a live FastMCP instance enables autodoc of **prompts**, **resources**, and **resource templates** — see the four new directives below. The collector accepts either: * A live instance: `"my_project.server:mcp"` (where `mcp = FastMCP(...)`). * A zero-argument factory: `"my_project.server:make_server"` returning a `FastMCP` instance. If the resolved object is not a `FastMCP` (no `local_provider` attribute), collection is skipped and a warning is logged. The collector also invokes the server's `register_all` / `_register_all` hook (if exported) to ensure components registered lazily appear in the docs; FastMCP's default `on_duplicate="error"` policy is suppressed for this call. --- # sphinx-autodoc-fastmcp Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/ (sphinx-autodoc-fastmcp)= # sphinx-autodoc-fastmcp ```{package-landing} sphinx-autodoc-fastmcp ``` --- # Kitchen sink Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/kitchen-sink/ (sphinx-autodoc-fastmcp-kitchen-sink)= # Kitchen sink ```{package-kitchen-sink} sphinx-autodoc-fastmcp ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/reference/ (sphinx-autodoc-fastmcp-reference)= # API Reference ## Config reference Generated from `app.add_config_value()` registrations in [`sphinx_autodoc_fastmcp/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-fastmcp/src/sphinx_autodoc_fastmcp/__init__.py). ```{eval-rst} .. autoconfigvalues:: sphinx_autodoc_fastmcp ``` ## Directive and role reference Generated from `app.add_directive()` and `app.add_role()` registrations in [`sphinx_autodoc_fastmcp/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-fastmcp/src/sphinx_autodoc_fastmcp/__init__.py) via `sphinx-autodoc-docutils`. ```{eval-rst} .. autodirectives:: sphinx_autodoc_fastmcp .. autoroles:: sphinx_autodoc_fastmcp ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-fastmcp/tutorial/ (sphinx-autodoc-fastmcp-tutorial)= # Tutorial ## Working usage examples Render one tool card: ````myst ```{eval-rst} .. fastmcp-tool:: my_project.docs.fastmcp_tools.list_sessions ``` ```` Render one tool's parameter table: ````myst ```{eval-rst} .. fastmcp-tool-input:: my_project.docs.fastmcp_tools.list_sessions ``` ```` Render a summary table grouped by safety tier: ````myst ```{eval-rst} .. fastmcp-tool-summary:: ``` ```` Add inline cross-references in prose: ````myst Use {tool}`list_sessions` for a linked badge, or {toolref}`delete_session` for a plain inline reference. ```` ### Prompts and resources After setting `fastmcp_server_module`, four MyST directives become available for documenting MCP prompts and resources: ````myst ```{fastmcp-prompt} my_prompt ``` ```{fastmcp-prompt-input} my_prompt ``` ```{fastmcp-resource} my_resource ``` ```{fastmcp-resource-template} my_resource_template ``` ```` Resources and resource templates accept either the friendly component name (`my_resource`) or the literal URI (`mem://my_resource`). When two distinct resources share a name, autodoc keeps the first registration and emits a warning — disambiguate by URI. ### `:ref:` cross-reference IDs Section IDs follow `fastmcp-{kind}-{name}` (canonical): ```text {ref}`fastmcp-tool-list-sessions` {ref}`fastmcp-prompt-greet` {ref}`fastmcp-resource-status` {ref}`fastmcp-resource-template-events-by-day` ``` Tool sections additionally register the bare slug as a back-compat alias (e.g. `{ref}`list-sessions`` continues to resolve), preserving links shipped before the kind-prefix introduction. Prompts, resources, and resource templates use the canonical ID only — no bare alias is created for them. --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-pytest-fixtures/examples/ (sphinx-autodoc-pytest-fixtures-examples)= # Examples ## Live demos ```{py:module} spf_demo_fixtures ``` ### Bulk autodoc ```{eval-rst} .. autofixtures:: spf_demo_fixtures :no-index: ``` ### Plugin page helper :::{auto-pytest-plugin} spf_demo_fixtures :package: sphinx-autodoc-pytest-fixtures Add project-specific usage notes here. The helper renders the install section, autodiscovery note, and full fixture summary/reference. ::: #### When to use `auto-pytest-plugin` Use this directive for a standard pytest plugin page where you want consistent house-style: an install section, the `pytest11` autodiscovery note, and a generated fixture summary and reference. #### autofixtures options | Option | Default | Description | |--------|---------|-------------| | `:order:` | `"source"` | `"source"` preserves module order; `"alpha"` sorts alphabetically | | `:exclude:` | (empty) | Comma-separated fixture names to skip | | `:no-index:` | (off) | Emit descriptions without registering fixtures in the domain index; use when the same module is documented twice on one page | ### Single autodoc entries ```{eval-rst} .. autofixture:: spf_demo_fixtures.demo_plain :no-index: ``` ```{eval-rst} .. autofixture:: spf_demo_fixtures.demo_session_factory :no-index: ``` ### Manual domain directive ```{eval-rst} .. py:fixture:: demo_deprecated :no-index: :deprecated: 1.0 :replacement: demo_plain :return-type: str Return a deprecated value. Use :fixture:`demo_plain` instead. ``` ```{package-reference} sphinx-autodoc-pytest-fixtures ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-pytest-fixtures) · [PyPI](https://pypi.org/project/sphinx-autodoc-pytest-fixtures/) --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-pytest-fixtures/how-to/ (sphinx-autodoc-pytest-fixtures-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_autodoc_pytest_fixtures"] pytest_fixture_lint_level = "warning" pytest_fixture_external_links = { "db": "https://docs.example.com/testing#db", } ``` `sphinx_autodoc_pytest_fixtures` automatically registers `sphinx_ux_badges`, `sphinx_ux_autodoc_layout`, and `sphinx_autodoc_typehints_gp` via `app.setup_extension()`. You do not need to add them separately to your `extensions` list. ## Registered configuration values ```{eval-rst} .. autoconfigvalues:: sphinx_autodoc_pytest_fixtures ``` --- # sphinx-autodoc-pytest-fixtures Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-pytest-fixtures/ (sphinx-autodoc-pytest-fixtures)= # sphinx-autodoc-pytest-fixtures ```{package-landing} sphinx-autodoc-pytest-fixtures ``` --- # Kitchen sink Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-pytest-fixtures/kitchen-sink/ (sphinx-autodoc-pytest-fixtures-kitchen-sink)= # Kitchen sink ```{package-kitchen-sink} sphinx-autodoc-pytest-fixtures ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-pytest-fixtures/tutorial/ (sphinx-autodoc-pytest-fixtures-tutorial)= # Tutorial ## Working usage examples Render a standard pytest plugin page: ````myst :::{auto-pytest-plugin} my_project.pytest_plugin :package: my-project ::: ```` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/examples/ (sphinx-autodoc-sphinx-examples)= # Examples ## Live demos This page also uses `sphinx-autodoc-docutils` to document the config-doc directives themselves, so the page demonstrates both config-value output and directive documentation. ### Render a single demo config value ```{eval-rst} .. autoconfigvalue:: sphinx_config_single_demo.demo_debug :no-index: ``` ### Bulk config values demo Renders all config values from a module at once: ```{eval-rst} .. autoconfigvalues:: sphinx_config_demo ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/how-to/ (sphinx-autodoc-sphinx-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_autodoc_sphinx"] ``` `sphinx_autodoc_sphinx` automatically registers `sphinx_ux_badges`, `sphinx_ux_autodoc_layout`, and `sphinx_autodoc_typehints_gp` via `app.setup_extension()`. You do not need to add them separately to your `extensions` list. --- # sphinx-autodoc-sphinx Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/ (sphinx-autodoc-sphinx)= # sphinx-autodoc-sphinx ```{package-landing} sphinx-autodoc-sphinx ``` --- # Kitchen sink Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/kitchen-sink/ (sphinx-autodoc-sphinx-kitchen-sink)= # Kitchen sink ```{package-kitchen-sink} sphinx-autodoc-sphinx ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/reference/ (sphinx-autodoc-sphinx-reference)= # API Reference ## Directive reference Generated from `app.add_directive()` registrations in [`sphinx_autodoc_sphinx/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-sphinx/src/sphinx_autodoc_sphinx/__init__.py) via `sphinx-autodoc-docutils` — a meta-loop where the package that documents config values uses its sibling package to document its own directives. ```{eval-rst} .. autodirectives:: sphinx_autodoc_sphinx ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-sphinx/tutorial/ (sphinx-autodoc-sphinx-tutorial)= # Tutorial ## Working usage examples Render one config value: ````myst ```{eval-rst} .. autoconfigvalue:: sphinx_fonts.sphinx_font_preload ``` ```` Render every config value from an extension module: ````myst ```{eval-rst} .. autoconfigvalues:: sphinx_config_demo ``` ```` Exclude specific config values (useful when two extensions register the same value and Sphinx warns on the duplicate ``confval``): ````myst ```{eval-rst} .. autoconfigvalues:: sphinx_gp_llms :exclude: site_url ``` ```` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-typehints-gp/dependents/ (sphinx-autodoc-typehints-gp-dependents)= # Dependents ```{package-dependents} sphinx-autodoc-typehints-gp ``` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-typehints-gp/examples/ (sphinx-autodoc-typehints-gp-examples)= # Examples ```{eval-rst} .. py:module:: api_demo_typehints_gp ``` The demos below exercise every rendering improvement `sphinx-autodoc-typehints-gp` ships beyond stock Sphinx + autodoc. Each section opens with a one-line "what's interesting here", then shows the rendered output from a small demo module ([`docs/_ext/api_demo_typehints_gp.py`](https://github.com/git-pull/gp-sphinx/blob/main/docs/_ext/api_demo_typehints_gp.py)), then a callout pointing at the specific HTML shape worth noticing. ## Source-text parameter defaults `autodoc_preserve_defaults=True` is on by default in `gp_sphinx.defaults`, so each method's `=…` default renders as the literal source text rather than the runtime `repr()`. Sentinel instances like `` become the symbolic name `DEFAULT_RETRY` instead. ## Dataclass `field(default_factory=…)` rendering The synthetic-init listener walks `dataclasses.fields(...)` after Sphinx introspects the dataclass and substitutes the factory call's source text. Stdlib container types render as their literal forms (`[]`, `{}`, `set()`, `frozenset()`, `()`); named callable factories render as `Name()`. ```{eval-rst} .. autoclass:: api_demo_typehints_gp.HookCounters ``` What to look for: the `__init__` signature shows `alerts=[], index={}, names=set(), tags=(), transports=[]` — no `` placeholders. ## Long module-level constants `GpDataDocumenter` / `GpAttributeDocumenter` route every `:value:` line through a resolver chain. `TruncateLongRepr(threshold=200)` collapses long values to `<...truncated, N chars>`; short values render unchanged. ```{eval-rst} .. autodata:: api_demo_typehints_gp.SHORT_DEFAULT .. autodata:: api_demo_typehints_gp.LONG_DEFAULT_RULES ``` What to look for: `SHORT_DEFAULT` shows `'admin'` directly; `LONG_DEFAULT_RULES` shows `<...truncated, N chars>` instead of the 20-tuple list blob. ## Cross-referenced default values Stage C's `DefaultValueXrefTransform` walks every `` inside a `
` signature, AST-parses the text, and turns documented identifier references into clickable cross-references in the same ` ` shape that inline `:py:obj:` roles produce. Undocumented or unparseable defaults fall back to plain text. ```{eval-rst} .. autofunction:: api_demo_typehints_gp.open_session ``` What to look for: the `scope=` and `retry=` defaults link to {py:attr}`~api_demo_typehints_gp.CacheScope.Session` and {py:data}`~api_demo_typehints_gp.DEFAULT_RETRY` respectively. Hover the rendered defaults — they're real anchors, not just styled text. ```{eval-rst} .. autofunction:: api_demo_typehints_gp.with_lambda_default ``` What to look for: the `callback=lambda: None` default falls back to plain text inside the `default_value` span — no broken-looking `` styling on something that can't link. ## Field-list xref styling `FieldListXrefStyleTransform` normalises every Python-domain `pending_xref` inside a field list to a single `` shape — the same HTML inline `:py:class:` roles produce. Parameter types, return types, and raises exception names all match. The whole `name (type, optional)` prefix on each parameter row is wrapped in `` so a single CSS rule renders the prefix in monospace; `Returns` prose stays in body font. The `open_session` autodoc above already demonstrates this — its `Parameters`, `Return`, and `Raises` sections each render the canonical shape on every Python identifier reference. ## Documented targets used by the demos ```{eval-rst} .. autoclass:: api_demo_typehints_gp.CacheScope :members: .. autoclass:: api_demo_typehints_gp.Transport .. autoexception:: api_demo_typehints_gp.ConnectionFailure .. autodata:: api_demo_typehints_gp.DEFAULT_RETRY ``` ```{package-reference} sphinx-autodoc-typehints-gp ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-typehints-gp/how-to/ (sphinx-autodoc-typehints-gp-how-to)= # How to ## Installation ```console $ pip install sphinx-autodoc-typehints-gp ``` ## Pipeline position Two hooks run independently: | Event | Hook | Priority | |-------|------|----------| | `autodoc-process-docstring` | NumPy section parser | default (not priority-controlled) | | `object-description-transform` | `merge_typehints` | **499** — before Sphinx's built-in `_merge_typehints` at 500 | Running at priority 499 means cross-referenced `:type:`/`:rtype:` fields are already in place before Sphinx's built-in handler runs. The built-in sees them and skips its own plain-text duplicates — cooperation, not conflict. ## Features - Resolves type hints statically without `exec()` or `typing.get_type_hints()`. - Works perfectly with `TYPE_CHECKING` blocks. - No text-level race conditions with Napoleon. - Exposes reusable helpers for annotation display classification and rendered type paragraphs used by the other autodoc packages. ## Shared layer `sphinx_autodoc_typehints_gp` serves as the shared internal annotation normalization layer for the `sphinx-autodoc-*` family. The symbols exported in `__all__` are intended for use by other `gp-sphinx` packages and by extension authors who want to reuse the same rendering pipeline. The API is stable within a `gp-sphinx` version range but does not carry the same backward-compatibility guarantees as `gp_sphinx.merge_sphinx_config()`. ## Choosing the right helper Four `build_*` functions span two axes: | | Resolved (`env` available) | Unresolved (annotation text only) | |---|---|---| | Raw paragraph | `build_resolved_annotation_paragraph` | `build_annotation_paragraph` | | Display-classified | `build_resolved_annotation_display_paragraph` | `build_annotation_display_paragraph` | Use `build_resolved_*` inside `doctree-resolved` event handlers where a `BuildEnvironment` is available. Use `build_*` when you have only the annotation string. ## Annotation display classification `classify_annotation_display()` returns an `AnnotationDisplay` with structured metadata for UI renderers. All values below are verified against the installed package: | Annotation input | `text` | `is_literal_enum` | `literal_members` | |---|---|---|---| | `str` | `"str"` | `False` | `()` | | `str \| None` | `"str \| None"` | `False` | `()` | | `str \| None` (`strip_none=True`) | `"str"` | `False` | `()` | | `Literal['open', 'closed']` | `"'open', 'closed'"` | `True` | `("'open'", "'closed'")` | | `int \| bool` | `"int \| bool"` | `False` | `()` | `is_literal_enum=True` lets rendering code produce individual badge chips for each member rather than a monolithic code string. This decision used to live in each consumer (FastMCP, pytest-fixtures, api-style); now it lives in `classify_annotation_display()` so no downstream package re-implements enum detection heuristics. ## Static resolution | Approach | `TYPE_CHECKING` block safe | Napoleon text-processing race | |---|---|---| | `typing.get_type_hints()` | No — resolves at import time | Yes — depends on import order | | `sphinx_stringify_annotation()` | Yes — resolves at Sphinx build time | No — no text processing | This extension uses `sphinx_stringify_annotation()` to resolve annotations at build time, making it safe with `TYPE_CHECKING` blocks and eliminating text-processing races with Napoleon. --- # sphinx-autodoc-typehints-gp Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-typehints-gp/ (sphinx-autodoc-typehints-gp)= # sphinx-autodoc-typehints-gp ```{package-landing} sphinx-autodoc-typehints-gp ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-autodoc-typehints-gp/tutorial/ (sphinx-autodoc-typehints-gp-tutorial)= # Tutorial ## Working usage examples Add `sphinx_autodoc_typehints_gp` to your `extensions` list in `conf.py`: ```python extensions = [ "sphinx.ext.autodoc", "sphinx_autodoc_typehints_gp", ] # Required: makes autodoc insert type annotations into parameter descriptions. # Without this, the type cross-referencing pipeline fires but has nothing to attach to. autodoc_typehints = "description" ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-fonts/dependents/ (sphinx-fonts-dependents)= # Dependents ```{package-dependents} sphinx-fonts ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-fonts/how-to/ (sphinx-fonts-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_fonts"] sphinx_fonts = [ { "family": "IBM Plex Sans", "package": "@fontsource/ibm-plex-sans", "version": "5.2.8", "weights": [400, 500, 600, 700], "styles": ["normal", "italic"], "subset": "latin", }, ] sphinx_font_preload = [ ("IBM Plex Sans", 400, "normal"), ] sphinx_font_css_variables = { "--font-stack": '"IBM Plex Sans", system-ui, sans-serif', } ``` ## Live specimen This site uses `sphinx-fonts`, so the samples below are rendered with the same template context that downstream themes receive. ```{raw} html

Sans stack

Sphinx DX should feel intentional, readable, and fast.

Monospace stack

merge_sphinx_config(project="demo", version="1.0.0")

``` ## Template context The extension injects these values during `html-page-context`: | Variable | Type | Description | | --- | --- | --- | | `font_faces` | `list[dict[str, str]]` | File metadata for generated `@font-face` declarations | | `font_preload_hrefs` | `list[str]` | Font filenames to preload | | `font_fallbacks` | `list[dict[str, str]]` | Metric-adjusted fallback declarations | | `font_css_variables` | `dict[str, str]` | CSS custom properties for theme font stacks | ## Notes - Fonts are cached under `~/.cache/sphinx-fonts`. - Non-HTML builders return early and do not download assets. - `sphinx-gp-theme` consumes this template context automatically; `gp-sphinx` preconfigures IBM Plex defaults for it. ```{package-reference} sphinx-fonts ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-fonts) · [PyPI](https://pypi.org/project/sphinx-fonts/) --- # sphinx-fonts Source: https://gp-sphinx.git-pull.com/packages/sphinx-fonts/ (sphinx-fonts)= # sphinx-fonts ```{package-landing} sphinx-fonts ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-fonts/reference/ (sphinx-fonts-reference)= # API Reference ## Configuration values ```{eval-rst} .. autoconfigvalues:: sphinx_fonts ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-llms/dependents/ (sphinx-gp-llms-dependents)= # Dependents ```{package-dependents} sphinx-gp-llms ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-llms/how-to/ (sphinx-gp-llms-how-to)= # How to ## Integration with gp-sphinx `sphinx_gp_llms` ships in {py:data}`~gp_sphinx.defaults.DEFAULT_EXTENSIONS`, so projects that build through {py:func}`~gp_sphinx.config.merge_sphinx_config` load it automatically. Passing `docs_url=` to that function auto-derives the URL input the extension needs: | Auto-derived | Source | | --- | --- | | `site_url` | `docs_url`, normalized to end in `/` | When `site_url` is unset, the extension logs at INFO and skips all output — no broken builds. ## Output formats ### `llms.txt` Structured Markdown index following the [llmstxt.org](https://llmstxt.org/) specification (Jeremy Howard, Answer.AI). The file gives LLM agents a curated entry point to the site's content: - **H1** — project name - **Blockquote** — first paragraph of the root document - **H2 sections** — one per `{toctree}` directive with a `:caption:` option; pages not in any captioned toctree fall into a "Documentation" section - **Bulleted links** — `[Page Title](full URL): first-paragraph description` per page ### `llms-full.txt` Concatenated full-content Markdown of every documentation page, following the community convention adopted by Anthropic, Cloudflare, and GitBook. Each page appears under a title header with a source URL, separated by `---` dividers. Source files are included as-is — MyST pages are already Markdown; RST pages are included verbatim. ### `docs.json` Agent-oriented manifest following the convention established by Lakebed (Ping). The JSON file provides structured metadata for machine consumption: - `agentEntrypoints` — pointers to `/docs.json`, `/llms.txt`, `/llms-full.txt` - `pages[]` — flat array with `title`, `description`, `section`, `url`, `markdownUrl`, and `headings[]` per page - `sourceRepository` — read from `html_theme_options["source_repository"]` ### Per-page `.md` twins Source file copies alongside each HTML page, following the "Markdown for Agents" convention (Cloudflare, Stripe, Anthropic, Vercel). Every HTML page at `/path/page.html` gets a sibling at `/path/page.md` containing the original source content. ## How the outputs are built All output files are generated at `build-finished` in the main process, iterating `app.env.found_docs` (the env-merged set of all documented files). This means: - **Incremental builds** produce complete output — no pages are missed because Sphinx only re-wrote a subset. - **Parallel builds** (`sphinx-build -j N`) work correctly — `found_docs` is merged across workers before `build-finished` fires. - **Non-HTML builders** (text, json, manpage) are skipped automatically — the handler checks for `get_target_uri`. Footer link injection runs via `html-page-context`, adding template variables (`llms_md_url`, `llms_txt_url`, etc.) only when the corresponding `llms_generate_*` flag is `True`. ## Event hooks ```text build-finished → _write_llm_outputs (llms.txt, llms-full.txt, docs.json, .md twins) html-page-context → _inject_llms_context (footer link variables) ``` Both live in [`sphinx_gp_llms/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-llms/src/sphinx_gp_llms/__init__.py). ## Footer integration When the extension is loaded and `site_url` is configured, the page footer's "Machine-readable" line includes links to Markdown (per-page `.md` twin), raw source (GitHub), docs.json, llms.txt, and llms-full.txt. Each link appears only when its corresponding output is enabled — disabling `llms_generate_json` removes the docs.json link from the footer. The footer renders LLM links independently of `source_repository`, so projects that configure `docs_url` but not `source_repository` still get the LLM output links. --- # sphinx-gp-llms Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-llms/ (sphinx-gp-llms)= # sphinx-gp-llms ```{package-landing} sphinx-gp-llms ``` ## Credits The output formats follow conventions established by their respective communities: - **`llms.txt`** — proposed by Jeremy Howard ([Answer.AI](https://www.answer.ai/)), September 2024. Specification at [llmstxt.org](https://llmstxt.org/). - **`llms-full.txt`** — community convention adopted by Anthropic, Cloudflare, GitBook, Hugging Face, and others. - **`docs.json`** — agent-manifest convention inspired by [Lakebed](https://docs.lakebed.dev/) (Ping, `github.com/pingdotgg/span`). - **Per-page `.md` twins** — convention popularized by Cloudflare ("[Markdown for Agents](https://developers.cloudflare.com/fundamentals/reference/markdown-for-agents/)"), Stripe, Anthropic, and Vercel. - **Footer layout** (`Source: docs/page.md · Machine-readable: Markdown, raw source, docs.json, llms.txt, llms-full.txt`) — inspired by [docs.lakebed.dev](https://docs.lakebed.dev/). ## A note on `docs.json` Sphinx already ships an inter-project linking mechanism: [`objects.inv`](https://github.com/sphinx-doc/sphinx/blob/v9.1.0/sphinx/util/inventory.py#L43), the inventory file that powers [intersphinx](https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html). It maps qualified names (classes, functions, config values) to URLs across Sphinx sites. It is not, however, designed for LLM consumption — the format is a compressed binary with a domain-specific schema oriented toward cross-reference resolution, not content discovery. `docs.json` fills a different role: a site-level beacon that tells agents where the documentation lives, what pages exist, and how to fetch them in Markdown. It carries `agentEntrypoints` (pointers to `llms.txt`, `llms-full.txt`, and itself), a flat `pages[]` array with per-page `markdownUrl` and `headings[]`, and the project's `sourceRepository`. There is no published specification for this format. We first noticed the convention at [Lakebed](https://docs.lakebed.dev/) (`github.com/pingdotgg/span`). Other documentation platforms also emit a file named `docs.json`, but those are typically site-builder configuration files (theme colors, navigation structure) closer to a `manifest.json` than an agent-oriented content manifest. --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-llms/reference/ (sphinx-gp-llms-reference)= # API Reference ## Config reference Generated from `app.add_config_value()` registrations in [`sphinx_gp_llms/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-llms/src/sphinx_gp_llms/__init__.py). ```{eval-rst} .. autoconfigvalues:: sphinx_gp_llms :exclude: site_url ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-opengraph/dependents/ (sphinx-gp-opengraph-dependents)= # Dependents ```{package-dependents} sphinx-gp-opengraph ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-opengraph/how-to/ (sphinx-gp-opengraph-how-to)= # How to ## Integration with gp-sphinx `sphinx_gp_opengraph` ships in {py:data}`~gp_sphinx.defaults.DEFAULT_EXTENSIONS`, so projects that build through {py:func}`~gp_sphinx.config.merge_sphinx_config` load it automatically. Passing `docs_url=` to that function auto-derives three of the most common config values: | Auto-derived | Source | | --- | --- | | `ogp_site_url` | `docs_url` | | `ogp_site_name` | `project` | | `ogp_image` | `"_static/img/icons/icon-192x192.png"` | The canonical reference for these and the other auto-derived values lives in {ref}`from-docs_url`. Any value passed via `**overrides` to `merge_sphinx_config()` wins over the auto-derived default — auto-computation runs first, overrides apply last. ## How the page-level meta tags are built For every page rendered by an HTML-family builder, the extension's `html-page-context` handler walks the resolved doctree and emits the following tags into `context["metatags"]`. The page is skipped when its front-matter sets `ogp_disable: true`. | Tag | Source | | --- | --- | | `og:title` | First heading of the page, with HTML stripped (`_title.py`) | | `og:type` | `ogp_type` (default `"website"`) | | `og:url` | `ogp_canonical_url or ogp_site_url`, joined with the page's relative URL | | `og:site_name` | `ogp_site_name`, or `project` when unset; suppressed when set to `False` | | `og:description` | First non-title body paragraph, truncated to `ogp_description_length`, HTML-escaped (`_description.py`) | | `og:image` | Page front-matter `og:image`, else `ogp_image`, else first in-page image when `ogp_use_first_image=True` | | `og:image:alt` | Front-matter `og:image:alt`, else `ogp_image_alt`, falling back to site name, then page title | | `` | Mirror of `og:description` when `ogp_enable_meta_description=True` and the page does not already define one (`_meta.py`) | The description extractor walks the document, skips title nodes and empty paragraphs, takes the first prose paragraph, and truncates at the configured cap. Embedded HTML quote characters are escaped with `"` before emission, so user content cannot break out of the attribute value. Custom raw markup listed in `ogp_custom_meta_tags` is appended verbatim after the structured tags — that is the supported escape hatch for Twitter card declarations and `og:image:width`/`og:image:height` hints. ## Event hooks ```text config-inited → _warn_if_social_cards_used (deprecation warning) html-page-context → html_page_context (per-page meta-tag emission) ``` Both hooks live in [`sphinx_gp_opengraph/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-opengraph/src/sphinx_gp_opengraph/__init__.py). There is no `builder-inited` or `build-finished` work — the extension is purely a per-page transformer. ## Trade-offs **`ogp_social_cards` is accepted but ignored.** The upstream extension ships a matplotlib renderer that builds per-page PNGs at `builder-inited`. sphinx-gp-opengraph deliberately omits the dependency to keep the install graph small. The config key remains registered so existing `conf.py` files do not error; setting it logs a single `WARNING` at `config-inited` directing users to the static-image workflow documented in the README. **`parallel_read_safe` and `parallel_write_safe` are both `True`.** The extension never writes shared state — every emission is self-contained inside the per-page hook — so it is safe under any `sphinx-build -j N` value. --- # sphinx-gp-opengraph Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-opengraph/ (sphinx-gp-opengraph)= # sphinx-gp-opengraph ```{package-landing} sphinx-gp-opengraph ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-opengraph/reference/ (sphinx-gp-opengraph-reference)= # API Reference ## Config reference Generated from `app.add_config_value()` registrations in [`sphinx_gp_opengraph/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-opengraph/src/sphinx_gp_opengraph/__init__.py). ```{eval-rst} .. autoconfigvalues:: sphinx_gp_opengraph ``` --- # Signatures (live) Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-opengraph/signatures/ (sphinx-gp-opengraph-signatures)= # Signatures (live) ```{live-signature} sphinx-gp-opengraph ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-sitemap/dependents/ (sphinx-gp-sitemap-dependents)= # Dependents ```{package-dependents} sphinx-gp-sitemap ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-sitemap/how-to/ (sphinx-gp-sitemap-how-to)= # How to ## Integration with gp-sphinx `sphinx_gp_sitemap` ships in {py:data}`~gp_sphinx.defaults.DEFAULT_EXTENSIONS`, so projects that build through {py:func}`~gp_sphinx.config.merge_sphinx_config` load it automatically. Passing `docs_url=` to that function auto-derives both URL inputs the extension needs: | Auto-derived | Source | | --- | --- | | `site_url` | `docs_url`, normalized to end in `/` | | `sitemap_url_scheme` | `"{link}"` (flat — no language or version segment) | The flat scheme overrides the upstream default of `"{lang}{version}{link}"` because git-pull.com sites deploy at the project root, with no language or version directory in the URL space. Multilingual or version-pinned hosts can still pass an explicit `sitemap_url_scheme` through `**overrides` — `merge_sphinx_config()` runs auto-derivation first and overrides last. The canonical mapping lives in {ref}`from-docs_url`. ## How `sitemap.xml` is built After every HTML-family build, the extension serializes one `` element per built page to `sitemap.xml` in the output directory. 1. **Init** — `builder-inited` initializes `env.temp_data["sphinx_gp_sitemap_links"]` to an empty list. 2. **Collect** — `html-page-context` fires once per page. The handler computes the relative URL using the builder's suffix (`html_file_suffix or ".html"` for the `html` builder; `…/` for `dirhtml`, with the index emitted as the empty string), drops it when any pattern in `sitemap_excludes` matches, and appends a `(relative_link, last_updated)` tuple to the list. 3. **Compose** — `build-finished` resolves `site_url` (or `html_baseurl` as fallback; if both are unset the build is logged at INFO and skipped silently). For each collected link the handler formats `site_url + sitemap_url_scheme.format(lang=…, version=…, link=…)`. The `lang` segment comes from `app.builder.config.language` followed by `/` (empty when no language is set); `version` likewise from `app.builder.config.version`. 4. **Hreflang** — when `sitemap_locales` resolves to a non-empty list (explicit value, or auto-detected sub-directories of every entry in `locale_dirs`), each `` gains `` siblings. The formatter rewrites underscores to hyphens for IANA compatibility (`pt_BR` → `pt-BR`). The sentinel `sitemap_locales = [None]` suppresses alternates explicitly. 5. **Lastmod** (optional) — when `sitemap_show_lastmod = True`, the `config-inited` handler runs `app.setup_extension("sphinx_last_updated_by_git")` once at the start of the build to lazy-load the supporting extension. If the import fails, sphinx-gp-sitemap logs a `WARNING` and disables the flag for the rest of the build — `` is omitted but everything else still emits. 6. **Serialize** — `xml.etree.ElementTree.write()` produces the file. When `sitemap_indent > 0`, `ElementTree.indent()` pretty-prints the tree with the configured width. ElementTree handles XML entity escaping for the URL text and attribute values automatically. ## Event hooks ```text config-inited → _maybe_enable_git_lastmod (lazy-load lastmod ext) build-finished → _write_sitemap (enumerate found_docs + XML serialization) ``` Both live in [`sphinx_gp_sitemap/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-sitemap/src/sphinx_gp_sitemap/__init__.py). Page enumeration runs once at `build-finished` over `app.env.found_docs` using `app.builder.get_target_uri(pagename)` for each URL — no `html-page-context` handler, so incremental builds (where Sphinx fires the hook only for re-written pages) still emit a complete sitemap. `app.env.found_docs` is part of the env Sphinx merges across parallel-read workers, so the extension is `parallel_write_safe` without per-handler aggregation logic. ## Trade-offs **Drop-in for `sphinx-sitemap` with stricter URL handling.** Upstream reconstructed page URLs as `pagename + html_file_suffix`, which diverges from the HTML builder's actual `` output when `html_link_suffix` is set (e.g. `"/"` for clean URLs) or when a pagename contains characters Sphinx URL-quotes. sphinx-gp-sitemap calls `app.builder.get_target_uri(pagename)` directly, matching the links Sphinx emits on the page itself. **`html_baseurl` is re-registered defensively.** Sphinx core registers `html_baseurl` on most modern versions, but older trees and some custom builders skip it. The `setup()` body wraps the `add_config_value("html_baseurl", …)` call in `contextlib.suppress(ExtensionError)` so the extension is robust against either layout. The bare `except BaseException` upstream uses is replaced by the narrow `ExtensionError` catch. --- # sphinx-gp-sitemap Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-sitemap/ (sphinx-gp-sitemap)= # sphinx-gp-sitemap ```{package-landing} sphinx-gp-sitemap ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-sitemap/reference/ (sphinx-gp-sitemap-reference)= # API Reference ## Config reference Generated from `app.add_config_value()` registrations in [`sphinx_gp_sitemap/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-sitemap/src/sphinx_gp_sitemap/__init__.py). ```{eval-rst} .. autoconfigvalues:: sphinx_gp_sitemap ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-theme/dependents/ (sphinx-gp-theme-dependents)= # Dependents ```{package-dependents} sphinx-gp-theme ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-theme/how-to/ (sphinx-gp-theme-how-to)= # How to ## Downstream `conf.py` ```python extensions = ["sphinx_gp_theme"] html_theme = "sphinx-gp-theme" html_theme_options = { "project_name": "my-project", "project_description": "Shared docs for my project.", "light_logo": "img/logo-light.svg", "dark_logo": "img/logo-dark.svg", "source_repository": "https://github.com/your-org/my-project/", "source_branch": "main", "source_directory": "docs/", } ``` ## Live theme notes - This site is rendered with `sphinx-gp-theme`. - The package badges, cards, sidebar project list, and deferred page transitions on this page are live theme output. - Dark mode is inherited from Furo; the theme options below control the extra git-pull behavior layered on top. ## Theme options Options declared in `theme.conf` and accepted through `html_theme_options`: | Option | Description | | --- | --- | | `announcement` | Banner content rendered above the header | | `dark_css_variables` | Dark-mode CSS variable overrides | | `dark_logo` | Logo path for dark mode | | `footer_icons` | Footer icon list with `name`, `url`, `html`, and `class` keys | | `light_css_variables` | Light-mode CSS variable overrides | | `light_logo` | Logo path for light mode | | `mask_icon` | Safari pinned-tab icon | | `project_description` | Project summary used by sidebar/meta templates | | `project_name` | Short project name | | `project_title` | Alternate long-form title | | `project_url` | Canonical project home URL | | `show_meta_app_icon_tags` | Emit app icon meta tags | | `show_meta_manifest_tag` | Emit web manifest link tag | | `show_meta_og_tags` | Emit Open Graph tags | | `sidebar_hide_name` | Hide the sidebar brand name when a logo is present | | `source_branch` | Source branch used for edit/view links | | `source_directory` | Repository path containing docs sources | | `source_edit_link` | Override the generated edit link | | `source_repository` | Repository URL used for source links and footer GitHub icon | | `source_view_link` | Override the generated view-source link | | `top_of_page_button` | Single top-of-page action, defaults to `edit` | | `top_of_page_buttons` | Multiple top-of-page actions | ## Bundled assets | File | Purpose | | --- | --- | | `theme/sidebar/brand.html` | Sidebar brand block | | `theme/sidebar/projects.html` | Cross-project navigation | | `theme/static/css/custom.css` | Base layout and typography overrides | | `theme/static/css/argparse-highlight.css` | CLI lexer highlighting rules | | `theme/static/js/spa-nav.js` | Deferred navigation enhancer | ## Relationship to gp-sphinx `gp-sphinx` sets this theme automatically via {py:func}`~gp_sphinx.config.merge_sphinx_config` and pre-populates `source_repository`, `source_branch`, `source_directory`, footer icons, and the IBM Plex font stacks consumed by the theme templates. ```{package-reference} sphinx-gp-theme ``` [Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-gp-theme) · [PyPI](https://pypi.org/project/sphinx-gp-theme/) --- # sphinx-gp-theme Source: https://gp-sphinx.git-pull.com/packages/sphinx-gp-theme/ (sphinx-gp-theme)= # sphinx-gp-theme ```{package-landing} sphinx-gp-theme ``` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/dependents/ (sphinx-ux-autodoc-layout-dependents)= # Dependents ```{package-dependents} sphinx-ux-autodoc-layout ``` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/examples/ (sphinx-ux-autodoc-layout-examples)= # Examples ## Live demos ```{py:module} api_demo_layout ``` ### Class with members (regions + fold) ```{eval-rst} .. autoclass:: api_demo_layout.LayoutDemo :members: ``` The class above renders with: - **narrative** region (class docstring) - **fields** region with fold (13 parameters > threshold of 10) - **members** region (connect, execute, close methods) ### Small function (no fold) ```{eval-rst} .. autofunction:: api_demo_layout.compact_function ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/how-to/ (sphinx-ux-autodoc-layout-how-to)= # How to ## Pipeline position Hooks `doctree-resolved` at priority **600**, after `sphinx-autodoc-api-style` at 500. Consumes the `api_slot` nodes that producer packages inject into `desc_signature` during earlier transforms, and composes them into the final `gp-sphinx-api-layout-right` subcomponent (badges, source link, permalink). The extension also overrides Sphinx's built-in `desc_signature` HTML visitor (`app.add_node(addnodes.desc_signature, override=True, ...)`). This is a deliberate platform decision: taking ownership of signature rendering allows the `gp-sphinx-api-link` permalink to be placed inside the managed layout rather than appended by Sphinx's default handler. | Event | Hook | Priority | |-------|------|----------| | `doctree-resolved` | `on_doctree_resolved` | 600 (after api-style at 500) | | `object-description-transform` | — | not used | ## Downstream `conf.py` With `gp-sphinx`: ```python conf = merge_sphinx_config( project="my-project", version="1.0.0", copyright="2026, Your Name", source_repository="https://github.com/your-org/my-project/", extra_extensions=["sphinx_ux_autodoc_layout"], api_layout_enabled=True, api_collapsed_threshold=10, ) ``` Or without `merge_sphinx_config`: ```python extensions = ["sphinx.ext.autodoc", "sphinx_ux_autodoc_layout"] api_layout_enabled = True ``` ## Configuration Generated from `app.add_config_value()` registrations in [`sphinx_ux_autodoc_layout/__init__.py`](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-ux-autodoc-layout/src/sphinx_ux_autodoc_layout/__init__.py). ```{eval-rst} .. autoconfigvalues:: sphinx_ux_autodoc_layout ``` ## Shared helper surface - `build_api_card_entry()` builds the shared inner `api-*` shell for section-card consumers such as FastMCP. - `build_api_summary_section()` wraps summary and index tables in the shared `gp-sphinx-api-summary` region. --- # sphinx-ux-autodoc-layout Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/ (sphinx-ux-autodoc-layout)= # sphinx-ux-autodoc-layout ```{package-landing} sphinx-ux-autodoc-layout ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/reference/ (sphinx-ux-autodoc-layout-reference)= # API Reference ## CSS classes | Class | Element | Purpose | |-------|---------|---------| | `gp-sphinx-api-container` | `
` | Managed autodoc shell | | `gp-sphinx-api-header` | `
` | Signature row shell | | `gp-sphinx-api-content` | `
` | Description/content shell | | `gp-sphinx-api-layout` | `
` | Header split between left and right | | `gp-sphinx-api-layout-left` | `
` | Signature text, custom disclosure, permalink | | `gp-sphinx-api-layout-right` | `
` | Badge container and source link | | `gp-sphinx-api-signature` | `
` | Compact signature row | | `gp-sphinx-api-link` | `` | Managed permalink in the left layout | | `gp-sphinx-api-badge-container` | `` | Wrapper for badge group output | | `gp-sphinx-api-source-link` | `` | Wrapper for the `[source]` link | | `gp-sphinx-api-description` | `
` | Wraps paragraphs, notes, examples | | `gp-sphinx-api-parameters` | `
` | Wraps field lists (Parameters, Returns) | | `gp-sphinx-api-footer` | `
` | Wraps nested method/attribute entries | | `gp-sphinx-api-region` | `
` | Compatibility alias on content sections | | `gp-sphinx-api-region--narrative` | `
` | Compatibility alias on narrative sections | | `gp-sphinx-api-region--fields` | `
` | Compatibility alias on parameter sections | | `gp-sphinx-api-region--members` | `
` | Compatibility alias on footer/member sections | | `gp-sphinx-api-fold` | `
` | Disclosure wrapper for large sections | | `gp-sphinx-api-fold-summary` | `` | Click target showing field count | ## API reference ```{eval-rst} .. autofunction:: sphinx_ux_autodoc_layout.build_api_card_entry .. autofunction:: sphinx_ux_autodoc_layout.build_api_summary_section .. autofunction:: sphinx_ux_autodoc_layout.build_api_table_section .. autofunction:: sphinx_ux_autodoc_layout.build_api_facts_section ``` ```{package-reference} sphinx-ux-autodoc-layout ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-autodoc-layout/tutorial/ (sphinx-ux-autodoc-layout-tutorial)= # Tutorial ## Working usage examples Render one compact function: ````myst ```{eval-rst} .. autofunction:: my_project.api.compact_function ``` ```` Render a class with grouped content regions and member entries: ````myst ```{eval-rst} .. autoclass:: my_project.api.LayoutDemo :members: ``` ```` --- # Dependents Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/dependents/ (sphinx-ux-badges-dependents)= # Dependents ```{package-dependents} sphinx-ux-badges ``` --- # Examples Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/examples/ (sphinx-ux-badges-examples)= # Examples ## Live demos Every variant rendered by the real `build_badge` / `build_badge_group` / `build_toolbar` API: ```{gp-sphinx-badge-demo} ``` --- # Explanation Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/explanation/ (sphinx-ux-badges-explanation)= # Explanation ## Downstream extensions All colour variants are provided by the shared palette above. Downstream extensions reference `SAB.*` constants instead of maintaining their own `sab-*` / `spf-*` / `sas-*` / `sadoc-*` colour classes. ```{list-table} :header-rows: 1 :widths: 35 65 * - Extension - Badge types used * - {doc}`/packages/sphinx-autodoc-fastmcp/index` - Safety tiers (readonly / mutating / destructive), MCP tool type (`smf-*` — FastMCP-specific colours not in shared palette) * - {doc}`/packages/sphinx-autodoc-api-style/index` - `SAB.TYPE_FUNCTION`, `SAB.TYPE_CLASS`, `SAB.TYPE_METHOD`, modifiers, `SAB.STATE_DEPRECATED` * - {doc}`/packages/sphinx-autodoc-pytest-fixtures/index` - `SAB.TYPE_FIXTURE`, `SAB.SCOPE_*`, `SAB.STATE_FACTORY`, `SAB.STATE_OVERRIDE`, `SAB.STATE_AUTOUSE` * - {doc}`/packages/sphinx-autodoc-sphinx/index` - `SAB.TYPE_CONFIG`, `SAB.MOD_REBUILD` * - {doc}`/packages/sphinx-autodoc-docutils/index` - `SAB.TYPE_DIRECTIVE`, `SAB.TYPE_ROLE`, `SAB.TYPE_OPTION` ``` --- # sphinx-ux-badges Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/ (sphinx-ux-badges)= # sphinx-ux-badges ```{package-landing} sphinx-ux-badges ``` --- # API Reference Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/reference/ (sphinx-ux-badges-reference)= # API Reference ## Colour palette All semantic badge colours live in `sab_palettes.css` (registered by this extension). Every `sphinx-autodoc-*` package uses the `SAB.*` constants instead of its own colour classes. The live demo below shows every variant. ```{list-table} :header-rows: 1 :widths: 30 30 40 * - Colour class - `SAB` constant - Used for * - `gp-sphinx-badge--type-function` - `SAB.TYPE_FUNCTION` - Python functions (blue) * - `gp-sphinx-badge--type-class` - `SAB.TYPE_CLASS` - Python classes (indigo) * - `gp-sphinx-badge--type-method` - `SAB.TYPE_METHOD` - Instance / class / static methods (cyan) * - `gp-sphinx-badge--type-property` - `SAB.TYPE_PROPERTY` - Properties (teal) * - `gp-sphinx-badge--type-attribute` - `SAB.TYPE_ATTRIBUTE` - Attributes (slate) * - `gp-sphinx-badge--type-data` - `SAB.TYPE_DATA` - Module-level data (grey) * - `gp-sphinx-badge--type-exception` - `SAB.TYPE_EXCEPTION` - Exceptions (rose/red) * - `gp-sphinx-badge--type-typealias` - `SAB.TYPE_TYPEALIAS` - Type aliases (violet) * - `gp-sphinx-badge--type-module` - `SAB.TYPE_MODULE` - Modules (green) * - `gp-sphinx-badge--mod-async` - `SAB.MOD_ASYNC` - async modifier (purple outline) * - `gp-sphinx-badge--mod-classmethod` - `SAB.MOD_CLASSMETHOD` - classmethod modifier (amber outline) * - `gp-sphinx-badge--mod-staticmethod` - `SAB.MOD_STATICMETHOD` - staticmethod modifier (grey outline) * - `gp-sphinx-badge--mod-abstract` - `SAB.MOD_ABSTRACT` - abstract modifier (indigo outline) * - `gp-sphinx-badge--mod-final` - `SAB.MOD_FINAL` - final modifier (emerald outline) * - `gp-sphinx-badge--state-deprecated` - `SAB.STATE_DEPRECATED` - deprecated (muted red, shared across domains) * - `gp-sphinx-badge--type-fixture` - `SAB.TYPE_FIXTURE` - pytest fixtures (green) * - `gp-sphinx-badge--scope-session` - `SAB.SCOPE_SESSION` - session-scope fixtures (amber) * - `gp-sphinx-badge--scope-module` - `SAB.SCOPE_MODULE` - module-scope fixtures (teal) * - `gp-sphinx-badge--scope-class` - `SAB.SCOPE_CLASS` - class-scope fixtures (slate) * - `gp-sphinx-badge--state-factory` - `SAB.STATE_FACTORY` - factory fixtures (amber outline) * - `gp-sphinx-badge--state-override` - `SAB.STATE_OVERRIDE` - override hooks (violet outline) * - `gp-sphinx-badge--state-autouse` - `SAB.STATE_AUTOUSE` - autouse fixtures (rose outline) * - `gp-sphinx-badge--type-config` - `SAB.TYPE_CONFIG` - Sphinx config values (amber) * - `gp-sphinx-badge--mod-rebuild` - `SAB.MOD_REBUILD` - Sphinx rebuild mode (grey outline) * - `gp-sphinx-badge--type-directive` - `SAB.TYPE_DIRECTIVE` - docutils directives (violet) * - `gp-sphinx-badge--type-role` - `SAB.TYPE_ROLE` - docutils roles (violet) * - `gp-sphinx-badge--type-option` - `SAB.TYPE_OPTION` - docutils directive options (violet) ``` ## API reference ```{eval-rst} .. autoclass:: sphinx_ux_badges.BadgeSpec :members: .. autofunction:: sphinx_ux_badges.build_badge_from_spec .. autofunction:: sphinx_ux_badges.build_badge .. autofunction:: sphinx_ux_badges.build_badge_group .. autofunction:: sphinx_ux_badges.build_toolbar .. autoclass:: sphinx_ux_badges.BadgeNode :no-members: .. rubric:: Constructor parameters .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Parameter - Default - Description * - ``text`` - ``""`` - Visible label. Empty string for icon-only badges. * - ``badge_tooltip`` - ``""`` - Hover text and ``aria-label``. * - ``badge_icon`` - ``""`` - Emoji character rendered via CSS ``::before``. * - ``badge_style`` - ``"full"`` - Structural variant: ``"full"``, ``"icon-only"``, ``"inline-icon"``. * - ``badge_size`` - ``""`` - Optional size: ``"xxs"``, ``"xs"``, ``"sm"``, ``"md"``, ``"lg"``, or ``"xl"``. Empty means default. * - ``tabindex`` - ``"0"`` - ``"0"`` for keyboard-focusable, ``""`` to skip. * - ``classes`` - ``None`` - Additional CSS classes (plugin prefix + color class). .. autoclass:: sphinx_ux_badges._css.SAB :members: :undoc-members: .. autofunction:: sphinx_ux_badges.setup ``` ## CSS custom properties All colors and metrics are exposed as CSS custom properties on `:root`. Override them in your project's `custom.css` or via {py:meth}`~sphinx.application.Sphinx.add_css_file`. ### Defaults ```css :root { /* ── Color hooks (set by downstream extensions) ────── */ --gp-sphinx-badge-bg: transparent; /* badge background */ --gp-sphinx-badge-fg: inherit; /* badge text color */ --gp-sphinx-badge-border: none; /* badge border shorthand */ /* ── Metrics ───────────────────────────────────────── */ --gp-sphinx-badge-font-size: 0.75em; --gp-sphinx-badge-font-weight: 700; --gp-sphinx-badge-padding-v: 0.35em; /* vertical padding */ --gp-sphinx-badge-padding-h: 0.65em; /* horizontal padding */ --gp-sphinx-badge-radius: 0.25rem; /* border-radius */ --gp-sphinx-badge-icon-gap: 0.28rem; /* gap between icon and label */ /* ── Depth (inset shadow on solid badges) ──────────── */ --gp-sphinx-badge-buff-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 2px rgba(0, 0, 0, 0.12); --gp-sphinx-badge-buff-shadow-dark-ui: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 2px rgba(0, 0, 0, 0.28); } ``` ### Property reference ```{list-table} :header-rows: 1 :widths: 30 70 * - Property - Purpose * - `--gp-sphinx-badge-bg` - Badge background color. Extensions set this per badge class (e.g. green for "readonly"). * - `--gp-sphinx-badge-fg` - Badge text color. Falls back to `inherit` when unset. * - `--gp-sphinx-badge-border` - Border shorthand (`1px solid #...`). Defaults to `none`. * - `--gp-sphinx-badge-font-size` - Font size. Context-aware sizing (headings, body, TOC) overrides this. * - `--gp-sphinx-badge-font-weight` - Font weight. Default `700` (bold). * - `--gp-sphinx-badge-padding-v` / `--gp-sphinx-badge-padding-h` - Vertical and horizontal padding. * - `--gp-sphinx-badge-radius` - Border radius for pill shape. * - `--gp-sphinx-badge-icon-gap` - Gap between the `::before` icon and the label text. * - `--gp-sphinx-badge-buff-shadow` - Subtle inset highlight + shadow for depth on light backgrounds. * - `--gp-sphinx-badge-buff-shadow-dark-ui` - Stronger inset shadow variant for dark theme / `prefers-color-scheme: dark`. ``` ## CSS class reference All classes use the `sab-` prefix (**s**phinx **a**utodoc **b**adges). ```{list-table} :header-rows: 1 :widths: 25 15 60 * - Class - Applied by - Description * - `gp-sphinx-badge` - `BadgeNode` - Base class. Always present on every badge. * - `gp-sphinx-badge--outline` - `build_badge(fill="outline")` - Transparent background, inherits text color. * - `gp-sphinx-badge--icon-only` - `build_badge(style="icon-only")` - 16 × 16 colored box with emoji `::before`. * - `gp-sphinx-badge--inline-icon` - `build_badge(style="inline-icon")` - Bare emoji inside a code chip, no background. * - `gp-sphinx-badge-group` - `build_badge_group()` - Flex container with `gap: 0.3rem` between badges. * - `gp-sphinx-toolbar` - `build_toolbar()` - Flex push-right (`margin-left: auto`) for title rows. * - `gp-sphinx-badge--size-xxs` - `build_badge(size="xxs")` / `BadgeNode(..., badge_size="xxs")` - Minimum size (status dots, very tight layouts). * - `gp-sphinx-badge--size-xs` - `build_badge(size="xs")` / `BadgeNode(..., badge_size="xs")` - Extra small (dense tables, tight UI). * - `gp-sphinx-badge--size-sm` - `build_badge(size="sm")` - Small inline badges. * - `gp-sphinx-badge--size-md` - `build_badge(size="md")` - Medium — larger than the default but smaller than `lg`. * - `gp-sphinx-badge--size-lg` - `build_badge(size="lg")` - Large (section titles, callouts). * - `gp-sphinx-badge--size-xl` - `build_badge(size="xl")` - Extra large (hero / landing emphasis). ``` ## Context-aware sizing Badge size adapts automatically based on where it appears in the document. CSS selectors handle it. Explicit size classes (`gp-sphinx-badge--size-xs` … `gp-sphinx-badge--size-xl`) override contextual sizing when present (higher specificity than context rules). ```{list-table} :header-rows: 1 :widths: 25 20 55 * - Context - Font size - Selectors * - Heading (`h2`, `h3`) - `0.68rem` - `.body h2 .gp-sphinx-badge`, `[role="main"] h3 .gp-sphinx-badge` * - Body (`p`, `li`, `td`, `a`) - `0.62rem` - `.body p .gp-sphinx-badge`, `[role="main"] li .gp-sphinx-badge`, etc. * - TOC sidebar - `0.58rem` - `.toc-tree .gp-sphinx-badge` (compact, with emoji icons) ``` --- # Tutorial Source: https://gp-sphinx.git-pull.com/packages/sphinx-ux-badges/tutorial/ (sphinx-ux-badges-tutorial)= # Tutorial ## Working usage examples `setup()` registers the extension with Sphinx: 1. {py:meth}`~sphinx.application.Sphinx.add_node` registers `BadgeNode` with HTML visitors (`visit_badge_html` / `depart_badge_html`). 2. {py:meth}`~sphinx.application.Sphinx.add_css_file` injects the shared `sphinx_ux_badges.css` stylesheet. 3. Downstream extensions call {py:meth}`~sphinx.application.Sphinx.setup_extension` to load the badge layer: ```python def setup(app: Sphinx) -> dict[str, Any]: app.setup_extension("sphinx_ux_badges") ``` `BadgeNode` subclasses {py:class}`docutils.nodes.inline`, so unregistered builders (text, LaTeX, man) fall back to `visit_inline` via Sphinx's MRO-based dispatch — no special handling needed. Build a grouped toolbar in your own directive or transform: ```python from sphinx_ux_badges import build_badge, build_badge_group, build_toolbar badge_group = build_badge_group( [ build_badge( "readonly", tooltip="Read-only operation", classes=["gp-sphinx-fastmcp__safety-readonly"], ), build_badge( "tool", tooltip="FastMCP tool entry", classes=["gp-sphinx-fastmcp__type-tool"], ), ], ) toolbar = build_toolbar(badge_group, classes=["my-extension-toolbar"]) ``` --- # How to Source: https://gp-sphinx.git-pull.com/packages/sphinx-vite-builder/how-to/ (sphinx-vite-builder-how-to)= # How to ## Two heads, one core ### [PEP 517](https://peps.python.org/pep-0517/) build backend Drop-in replacement for `hatchling.build`. Runs `pnpm exec vite build` before delegating wheel/sdist construction to hatchling. End users who `pip install` from PyPI don't need pnpm or Node — the wheel ships with the static assets already populated. ```toml # packages/your-theme/pyproject.toml [build-system] requires = ["hatchling>=1.0", "sphinx-vite-builder"] build-backend = "sphinx_vite_builder.build" backend-path = ["../sphinx-vite-builder/src"] # for in-tree workspace consumption ``` ### Sphinx extension Loaded from `conf.py`. Hooks `builder-inited` and `build-finished` so `sphinx-build` and `sphinx-autobuild` automatically run the right vite invocation: a one-shot `pnpm exec vite build` for plain `sphinx-build` (or `sphinx_vite_builder_mode = "prod"`), a long-lived `pnpm exec vite build --watch` child process for `sphinx-autobuild` (or `sphinx_vite_builder_mode = "dev"`), with graceful SIGTERM → SIGKILL teardown on signal / `atexit`. ```python # docs/conf.py extensions = ["sphinx_vite_builder"] sphinx_vite_builder_mode = "auto" # "auto" | "dev" | "prod" sphinx_vite_builder_root = "/abs/path/to/web" ``` `"auto"` resolves to `"dev"` when the build is running under `sphinx-autobuild` (detected via `SPHINX_AUTOBUILD` env var, `argv[0]`, or parent-process inspection on Linux), otherwise `"prod"`. Setting `sphinx_vite_builder_root` to `None` (the default) makes the extension a complete no-op — useful when the consumer is installed from a wheel where the static tree is already pre-baked. ## Fast-fail diagnostics When prerequisites are missing the backend / extension raises actionable errors rather than producing broken output: - `PnpmMissingError` — `pnpm` not on `PATH`; hint includes `corepack enable`, the [pnpm.io/installation](https://pnpm.io/installation) URL, and a per-CI YAML/config snippet (GitHub Actions, CircleCI, Azure Pipelines, GitLab CI) when the build is detected to be running in CI. - `NodeModulesInstallError` — `pnpm install` exited non-zero; hint includes the rerun command and captured stderr. - `ViteFailedError` — `pnpm exec vite build` exited non-zero; hint surfaces the captured stderr. Set `SPHINX_VITE_BUILDER_SKIP=1` in the environment to short-circuit the backend (e.g., when an external orchestration handles vite). ```{package-reference} sphinx-vite-builder ``` --- # sphinx-vite-builder Source: https://gp-sphinx.git-pull.com/packages/sphinx-vite-builder/ (sphinx-vite-builder)= # sphinx-vite-builder ```{package-landing} sphinx-vite-builder ``` --- # Code Style Source: https://gp-sphinx.git-pull.com/project/code-style/ # Code Style ## Formatting gp-sphinx uses [ruff](https://github.com/astral-sh/ruff) for both linting and formatting. ```console $ uv run ruff format . ``` ```console $ uv run ruff check . --fix --show-fixes ``` ## Type Checking Strict [mypy](https://mypy-lang.org/) is enforced across `src/` and `tests/`. ```console $ uv run mypy . ``` ## Docstrings Follow [NumPy docstring style](https://numpydoc.readthedocs.io/en/latest/format.html) for all public functions, methods, and classes. --- # Contributing Source: https://gp-sphinx.git-pull.com/project/contributing/ # Contributing Install [git] and [uv]. Clone: ```console $ git clone https://github.com/git-pull/gp-sphinx.git ``` ```console $ cd gp-sphinx ``` Install packages: ```console $ uv sync --all-packages --all-extras --group dev ``` ## Tests Preferred local commands use a fixed pytest temp root under `.cache/` and disable tmp-path retention for speed. `just test` keeps full coverage, while `just test-fast` is a feedback loop only and intentionally excludes `integration` tests: ```console $ just test ``` ```console $ uv run pytest ``` Use raw `uv run pytest` when you want the conservative direct runner without the local temp-dir optimization. Fast local loop without doctest-modules or integration tests: ```console $ just test-fast ``` Canonical direct pytest command for the same fast lane: ```console $ uv run pytest \ -o "addopts=--tb=short --no-header --showlocals" \ -o tmp_path_retention_policy=none \ --basetemp="$(pwd)/.cache/pytest-fast-direct" \ -q \ --capture=tee-sys \ tests \ -m "not integration" ``` Do not use the fast lane to reason about full-suite coverage or total suite performance; it is intentionally deselected for local iteration. ### Automatically run tests on file save 1. `just start` (via [pytest-watcher], full local lane) 2. `just start-fast` for the fast local loop 3. `just watch-test` (requires installing [entr(1)]) [pytest-watcher]: https://github.com/olzhasar/pytest-watcher ## Documentation Default preview server: http://localhost:3124 [sphinx-autobuild] will automatically build the docs, watch for file changes and launch a server. From home directory: `just start-docs` From inside `docs/`: `just start` [sphinx-autobuild]: https://github.com/executablebooks/sphinx-autobuild ### Manual documentation (the hard way) `cd docs/` and `just html` to build. `just serve` to start http server. Helpers: `just build-docs`, `just serve-docs` Rebuild docs on file change: `just watch-docs` (requires [entr(1)]) Rebuild docs and run server via one terminal: `just dev-docs` (requires above) ## Test hierarchy Pick the **lightest** level that exercises the behavior: | Level | When to use | Speed | |---|---|---| | **Pure unit** | Strings, dicts, dataclasses — no nodes, no Sphinx | microseconds | | **Docutils tree unit** | Constructing `docutils.nodes.*` or `sphinx.addnodes.*` directly | microseconds | | **Snapshot unit** | Large or complex output — assert via `snapshot_doctree` | microseconds | | **Sphinx integration** (`@pytest.mark.integration`) | Must verify actual HTML output or Sphinx event wiring | 2–10 s | The `just test-fast` lane skips integration tests for rapid feedback. The full `just test` lane runs everything. ### Scenario caching Integration tests use the harness in `tests/_sphinx_scenarios.py`. `build_shared_sphinx_result()` caches builds by a SHA-256 content-hash digest, achieving a **9.5x speedup** (~40 s to ~4.2 s for 916 tests). Key rules: - Always `scope="module"` or `scope="session"` on build fixtures — never `scope="function"` - Use `purge_modules` to remove synthetic Python modules from `sys.modules` before the initial build - Use `SCENARIO_SRCDIR_TOKEN` + `substitute_srcdir=True` for `sys.path` injection in scenario `conf.py` files ### Snapshot testing The project uses [syrupy](https://github.com/toptal/syrupy) for snapshot assertions. Three custom fixtures (from `tests/_snapshots.py`) normalize their inputs before asserting: - `snapshot_doctree(doctree)` — normalizes a `nodes.Node` - `snapshot_html_fragment(html)` — strips ANSI, normalizes whitespace - `snapshot_warnings(warnings)` — strips noise lines and ANSI codes Update stored snapshots after intentional output changes: ```console $ uv run pytest --snapshot-update ``` [git]: https://git-scm.com/ [uv]: https://github.com/astral-sh/uv [entr(1)]: http://eradman.com/entrproject/ [`entr(1)`]: http://eradman.com/entrproject/ --- # Project Source: https://gp-sphinx.git-pull.com/project/ (project)= # Project Information for contributors and maintainers. ::::{grid} 1 1 2 2 :gutter: 2 2 3 3 :::{grid-item-card} Contributing :link: contributing :link-type: doc Development setup, running tests, submitting PRs. ::: :::{grid-item-card} Code Style :link: code-style :link-type: doc Ruff, mypy, NumPy docstrings, import conventions. ::: :::{grid-item-card} Releasing :link: releasing :link-type: doc Release checklist and version policy. ::: :::: ```{toctree} :hidden: contributing code-style releasing ``` --- # Releasing Source: https://gp-sphinx.git-pull.com/project/releasing/ # Releasing ## Version Policy gp-sphinx is pre-1.0. Minor version bumps may include breaking changes. All publishable workspace packages use a shared lockstep version. The root `gp-sphinx-workspace` package stays a bootstrap package, but its version should stay aligned with the publishable package set. ## Release Process [uv] handles virtualenv creation, package requirements, versioning, building, and publishing. There is no setup.py or requirements files. 1. Update `CHANGES` with release notes 2. Bump the shared version in the root `pyproject.toml` and in every package under `packages/*/pyproject.toml` 3. Update any exposed `__version__` values so they match the shared package version 4. Keep first-party workspace dependencies pinned exactly to the shared version 5. Commit and tag with the repo-wide release format: ```console $ git commit -m 'build(release): Tag v0.0.1a7' ``` ```console $ git tag v0.0.1a7 ``` 6. Push: ```console $ git push ``` ```console $ git push --tags ``` 7. GitHub Actions validates the shared version, builds all publishable packages, smoke-tests the built artifacts, and publishes them to PyPI [uv]: https://github.com/astral-sh/uv --- # Quickstart Source: https://gp-sphinx.git-pull.com/quickstart/ (quickstart)= # Quickstart ## Installation For latest official version: ```console $ pip install --user gp-sphinx ``` Upgrading: ```console $ pip install --user --upgrade gp-sphinx ``` (developmental-releases)= ### Developmental releases New versions of gp-sphinx are published to PyPI as alpha, beta, or release candidates. In their versions you will see notification like `a1`, `b1`, and `rc1`, respectively. `1.0.0b4` would mean the 4th beta release of `1.0.0` before general availability. - [pip]\: ```console $ pip install --user --upgrade --pre gp-sphinx ``` - [pipx]\: ```console $ pipx install --suffix=@next 'gp-sphinx' --pip-args '\--pre' --force ``` - [uv]\: ```console $ uv add gp-sphinx --prerelease allow ``` via trunk (can break easily): - [pip]\: ```console $ pip install --user -e git+https://github.com/git-pull/gp-sphinx.git#egg=gp-sphinx ``` - [uv]\: ```console $ uv add gp-sphinx --from git+https://github.com/git-pull/gp-sphinx.git ``` ## Usage In your project's `docs/conf.py`: ```python """Sphinx configuration for my-project.""" from __future__ import annotations from gp_sphinx.config import merge_sphinx_config import my_project conf = merge_sphinx_config( project="my-project", version=my_project.__version__, copyright="2026, Tony Narlock", source_repository="https://github.com/git-pull/my-project/", intersphinx_mapping={ "py": ("https://docs.python.org/", None), }, ) globals().update(conf) ``` ### Adding extra extensions ```python conf = merge_sphinx_config( # ... extra_extensions=["sphinx_autodoc_argparse.exemplar", "sphinx_click"], ) ``` ### Removing default extensions ```python conf = merge_sphinx_config( # ... remove_extensions=["sphinx_design"], ) ``` ### Custom theme options ```python conf = merge_sphinx_config( # ... light_logo="img/my-logo.svg", dark_logo="img/my-logo-dark.svg", theme_options={"sidebar_hide_name": True}, ) ``` ## Your first build Create a docs directory with a static assets folder: ```console $ mkdir -p docs/_static ``` Create a minimal `docs/index.md`: ```markdown # My Project Welcome to my project documentation. ``` Create `docs/conf.py` using the pattern from {ref}`Usage ` above. Build the HTML output: ```console $ uv run sphinx-build -b html docs docs/_build/html ``` Open `docs/_build/html/index.html` in your browser to see the result. ## Seeing the autodoc design system The build above renders a Furo-themed page with IBM Plex fonts. To see the full autodoc stack — badges, type hints, and card layout — document a Python module. Create a file `my_module.py` next to your `docs/` directory: ```python """Demo module for the autodoc design system.""" from __future__ import annotations from typing import Any def get_user( *, user_id: int, use_cache: bool = True, ) -> dict[str, Any]: """Fetch a user from the database. Parameters ---------- user_id : int The ID of the user to fetch. use_cache : bool If ``True``, attempts to use a cache. Returns ------- dict[str, Any] A dictionary of user properties. """ return {"id": user_id, "name": "Demo User"} ``` Enable the API style extension in your `docs/conf.py`: ```python conf = merge_sphinx_config( # ... existing parameters ... extra_extensions=["sphinx_autodoc_api_style"], ) ``` Create `docs/api.md`: ````markdown # API Reference ```{eval-rst} .. automodule:: my_module :members: ``` ```` Rebuild: ```console $ uv run sphinx-build -b html docs docs/_build/html ``` Open `docs/_build/html/api.html`. The function renders with type and modifier **badges**, clean **type hints** with cross-referenced links, and a **card layout** with parameter sections. See the {doc}`gallery` for a full showcase of every component. [pip]: https://pip.pypa.io/en/stable/ [pipx]: https://pypa.github.io/pipx/docs/ [uv]: https://docs.astral.sh/uv/ --- # What’s new Source: https://gp-sphinx.git-pull.com/whats-new/ (whats-new)= # What's new The `autodoc-improvements` branch introduces a unified **autodoc design system** — eight major advancements that transform how the documentation stack works. See the {doc}`gallery` for a visual showcase. ## New packages Two new foundational packages form the core of the rendering pipeline: - {doc}`sphinx-ux-autodoc-layout ` — componentized autodoc output with semantic regions, parameter folding, managed signatures, and card containers. - {doc}`sphinx-autodoc-typehints-gp ` — single-package replacement for `sphinx-autodoc-typehints` and `sphinx.ext.napoleon`. Resolves annotations statically at build time with no monkey-patching. ## Unified badge system All badge colours have been consolidated into {doc}`sphinx-ux-badges `. Every downstream package references `SAB.*` constants instead of maintaining its own colour classes — one palette, thirty-plus colour variants, full light/dark theming. ## Shared layout stack The autodoc extensions ({doc}`api-style `, {doc}`argparse `, {doc}`docutils `, {doc}`fastmcp `, {doc}`pytest-fixtures `, {doc}`sphinx `) now all share the same layout, badge, and typehint infrastructure. A change in the foundational layout package propagates instantly and consistently. ## argparse Sphinx domain {doc}`sphinx-autodoc-argparse ` now ships a real Sphinx `Domain` subclass. Programs, options, subcommands, and positional arguments are individually addressable via `:argparse:program:`, `:argparse:option:`, `:argparse:subcommand:`, and `:argparse:positional:` xref roles. Two auto-generated indices — `argparse-programsindex` (alphabetised programs) and `argparse-optionsindex` (options grouped by program) — give a workspace overview. `:option:` / `std:cmdoption` continues to resolve for intersphinx consumers. ## Three-tier package organization The workspace has been restructured into a clear {doc}`three-tier architecture `: shared infrastructure at the bottom, domain packages in the middle, and the theme/coordinator at the top. Lower layers never depend on higher ones. ## 9.5x test speedup Shared Sphinx scenario caching via `tests/_sphinx_scenarios.py` reduced full-suite runtime from ~40 s to ~4.2 s for 916 tests. Builds are keyed by a SHA-256 content-hash digest and reused across all tests that share the same scenario. ## Snapshot testing [Syrupy](https://github.com/toptal/syrupy) snapshot assertions lock in doctree structure, rendered HTML, and warning output. Three custom fixtures normalize build-path churn and docutils version noise so that snapshots stay stable across environments. ## Doctree-first testing The majority of tests now operate directly on the docutils doctree — constructing `nodes.*` objects in Python — instead of running full Sphinx builds. This makes tests faster, more precise, and easier to debug. ## sphinx-vite-builder: Vite + pnpm orchestration end-to-end {doc}`sphinx-vite-builder ` consolidates the workspace's Vite story into a single package with three orthogonal activation paths sharing one async-subprocess core: - **PEP 517 build backend** — `build-backend = "sphinx_vite_builder.build"` runs `pnpm exec vite build` before delegating wheel/sdist construction to `hatchling.build`. End users who `pip install` from PyPI get a wheel with the static tree pre-baked at release time and never need pnpm or Node. - **Hatchling build hook** — `[tool.hatch.build.hooks.vite]` composes with any other hatchling hook stack, so projects already using `build-backend = "hatchling.build"` can adopt Vite without swapping the backend. - **Sphinx extension** — `extensions = ["sphinx_vite_builder"]` in `conf.py` auto-orchestrates Vite during docs builds: a one-shot `pnpm exec vite build` for plain `sphinx-build`, a long-running `pnpm exec vite build --watch` child process under `sphinx-autobuild`, with graceful SIGTERM → SIGKILL teardown on signal / `atexit`. The whole product is the **wheel-vs-source asymmetry**: a `web/` directory triggers strict orchestration with fast-fail diagnostics (`PnpmMissingError`, `NodeModulesInstallError`, `ViteFailedError`, each carrying a copy-pasteable hint), while an absent `web/` (the unpacked-sdist case) short-circuits cleanly so wheels published to PyPI need zero toolchain on the consumer side. Errors are self-healing in CI: detected providers (GitHub Actions, CircleCI, Azure Pipelines, GitLab CI) get the right setup recipe inlined into the error message. The legacy `gp-sphinx-vite` extension has been retired in favour of `sphinx-vite-builder`; consumers using `merge_sphinx_config(vite_orchestration=True)` continue to work without code changes. ---