Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ $ uv add gp-sphinx --prerelease allow

### Features

- `sphinx-autodoc-fastmcp`: new Sphinx extension for FastMCP tool docs (card-style
`desc` layouts, safety badges, MyST directives, cross-reference roles)
- `sphinx-autodoc-badges`: shared badge node (`BadgeNode`), builder API
(`build_badge`, `build_badge_group`, `build_toolbar`), and base CSS
layer shared by `sphinx-autodoc-fastmcp`, `sphinx-autodoc-api-style`,
and `sphinx-autodoc-pytest-fixtures` (#13)
- `sphinx-autodoc-badges`: explicit size variants `xs` / `sm` / `lg` / `xl` via
`build_badge(size=...)` and `BadgeNode(badge_size=...)` — compose with any
fill, style, or color class (#13)
- Initial release of `gp_sphinx` shared documentation platform
- `merge_sphinx_config()` API for building complete Sphinx config from shared defaults
- Shared extension list, theme options, MyST config, font config
Expand All @@ -38,9 +47,17 @@ $ uv add gp-sphinx --prerelease allow
`sphinx-autodoc-api-style`, `sphinx-autodoc-pytest-fixtures`,
`sphinx-gptheme`, and docs (650 is not a standard Fontsource weight,
so browsers were synthesizing bold instead of using the real font file)
- Badge background colors, border colors, and dotted-underline tooltips lost
after `BadgeNode` (`<span>`) replaced `<abbr>` in `sphinx-autodoc-api-style`
and `sphinx-autodoc-pytest-fixtures`; restored via element-agnostic CSS
selectors and correct fill defaults (#13)

### Workspace packages

- `sphinx-autodoc-badges` — Shared badge node, builders, and base CSS for
safety tiers, scope, and kind labels. Extensions add color layers on top;
TOC sidebar shows compact badges with emoji icons and subtle inset depth on
solid pills (#13)
- `sphinx-autodoc-pytest-fixtures` — Sphinx autodocumenter for pytest fixtures.
Registers `py:fixture` as a domain object type with `autofixture::` for
single-fixture docs, `autofixtures::` for bulk module discovery, and
Expand Down
1 change: 1 addition & 0 deletions docs/_ext/package_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
... "sphinx-gptheme",
... "sphinx-argparse-neo",
... "sphinx-autodoc-docutils",
... "sphinx-autodoc-fastmcp",
... "sphinx-autodoc-pytest-fixtures",
... "sphinx-autodoc-sphinx",
... }
Expand Down
149 changes: 149 additions & 0 deletions docs/_ext/sab_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
"""Live badge demo directive for the sphinx-autodoc-badges docs page.

Renders every badge variant using the real ``build_badge`` /
``build_badge_group`` / ``build_toolbar`` API so the page exercises
the actual Python + CSS pipeline.
"""

from __future__ import annotations

import typing as t

from docutils import nodes
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective
from sphinx_autodoc_badges import build_badge, build_badge_group, build_toolbar


class BadgeDemoDirective(SphinxDirective):
"""Insert a gallery of badge variants into the doctree."""

has_content = False
required_arguments = 0

def run(self) -> list[nodes.Node]:
"""Build a gallery of every badge variant."""
result: list[nodes.Node] = []

def _section(title: str) -> nodes.paragraph:
p = nodes.paragraph()
p += nodes.strong(text=title)
return p

def _row(*badge_nodes: nodes.Node, label: str = "") -> nodes.paragraph:
p = nodes.paragraph()
for n in badge_nodes:
p += n
p += nodes.Text(" ")
if label:
p += nodes.literal(text=label)
return p

result.append(_section("Size variants (xs / sm / default / lg / xl)"))
result.append(
_row(
build_badge("xs", size="xs", tooltip="Extra small"),
build_badge("sm", size="sm", tooltip="Small"),
build_badge("md", tooltip="Default (no size class)"),
build_badge("lg", size="lg", tooltip="Large"),
build_badge("xl", size="xl", tooltip="Extra large"),
label='build_badge("lg", size="lg")',
)
)

result.append(_section("Filled (default)"))
result.append(
_row(
build_badge("label", tooltip="Default filled badge"),
label='build_badge("label")',
)
)
result.append(
_row(
build_badge(
"with icon",
icon="\U0001f50d",
tooltip="Badge with emoji icon",
),
label='build_badge("with icon", icon="\\U0001f50d")',
)
)

result.append(_section("Outline"))
result.append(
_row(
build_badge("outline", fill="outline", tooltip="Outline variant"),
label='build_badge("outline", fill="outline")',
)
)

result.append(_section("Icon-only"))
result.append(
_row(
build_badge(
"",
style="icon-only",
icon="\U0001f50d",
tooltip="Icon-only badge",
),
label='build_badge("", style="icon-only", icon="\\U0001f50d")',
)
)

result.append(_section("Inline-icon (inside code chips)"))
code = nodes.literal(text="some_function()")
inline_icon = build_badge(
"",
style="inline-icon",
icon="\u270f\ufe0f",
tooltip="Inline icon",
tabindex="",
)
wrapper = nodes.paragraph()
wrapper += inline_icon
wrapper += code
wrapper += nodes.Text(" ")
wrapper += nodes.literal(
text='build_badge("", style="inline-icon", icon="\\u270f\\ufe0f")'
)
result.append(wrapper)

result.append(_section("Badge group"))
group = build_badge_group(
[
build_badge("alpha", tooltip="First"),
build_badge("beta", tooltip="Second"),
build_badge("gamma", tooltip="Third"),
]
)
result.append(_row(group, label="build_badge_group([...badges...])"))

result.append(_section("Toolbar (push-right in flex heading)"))
tb = build_toolbar(
build_badge_group(
[
build_badge(
"readonly",
icon="\U0001f50d",
tooltip="Read-only",
),
build_badge("tool", tooltip="MCP tool"),
]
)
)
heading_container = nodes.container(classes=["sab-demo-toolbar-heading"])
heading_p = nodes.paragraph()
heading_p += nodes.strong(text="Example heading ")
heading_p += tb
heading_container += heading_p
result.append(heading_container)
result.append(_row(label="build_toolbar(build_badge_group([...]))"))

return result


def setup(app: Sphinx) -> dict[str, t.Any]:
"""Register the ``sab-badge-demo`` directive."""
app.add_directive("sab-badge-demo", BadgeDemoDirective)
app.add_css_file("css/sab_demo.css")
return {"version": "0.1", "parallel_read_safe": True}
9 changes: 9 additions & 0 deletions docs/_static/css/sab_demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.sab-demo-toolbar-heading > p {
display: flex;
align-items: center;
gap: 0.45rem;
background: var(--color-background-secondary);
border: 1px solid var(--color-background-border);
border-radius: 0.5rem;
padding: 0.5rem 1rem;
}
6 changes: 6 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-docutils" / "src"))
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-sphinx" / "src"))
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-api-style" / "src"))
sys.path.insert(
0,
str(project_root / "packages" / "sphinx-autodoc-badges" / "src"),
)
sys.path.insert(0, str(cwd / "_ext")) # docs demo modules

import gp_sphinx # noqa: E402
Expand All @@ -38,6 +42,8 @@
source_branch="main",
extra_extensions=[
"package_reference",
"sab_demo",
"sphinx_autodoc_badges",
"sphinx_autodoc_api_style",
"sphinx_autodoc_pytest_fixtures",
"sphinx_autodoc_docutils",
Expand Down
4 changes: 3 additions & 1 deletion docs/packages/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Packages

Eight workspace packages, each independently installable.
Ten workspace packages, each independently installable.

```{workspace-package-grid}
```
Expand All @@ -10,7 +10,9 @@ Eight workspace packages, each independently installable.

gp-sphinx
sphinx-autodoc-api-style
sphinx-autodoc-badges
sphinx-autodoc-docutils
sphinx-autodoc-fastmcp
sphinx-autodoc-sphinx
sphinx-autodoc-pytest-fixtures
sphinx-fonts
Expand Down
Loading