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
13 changes: 10 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,23 @@ jobs:

steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install tox tox-gh-actions
uv sync --locked --extra dev
uv pip install tox-gh-actions

- name: Test with tox
run: |
tox
uv run tox

- uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/docs-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,20 @@ jobs:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
python-version-file: "pyproject.toml"

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e .[docs,viz]
uv sync --locked --extra docs

- name: Test build docs
run: |
BUILDDIR=_build/main make -C docs/ local
uv run make -C docs/ local

- uses: rossjrw/pr-preview-action@v1
with:
source-dir: docs/_build/main
source-dir: docs/_build/dev
if: github.event_name == 'pull_request'
19 changes: 13 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,31 @@ jobs:
with:
# require all of history to see all tagged versions' docs
fetch-depth: 0
- uses: actions/setup-python@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
python-version-file: "pyproject.toml"

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e .[docs,viz]
uv sync --locked --extra docs

- name: Checkout gh-pages
# As we already did a deploy of gh-pages above, it is guaranteed to be there
# so check it out so we can selectively build docs below
uses: actions/checkout@v6
with:
ref: gh-pages
path: docs/_build

- name: Build docs
# Use the args we normally pass to sphinx-build, but run sphinx-multiversion
# Use the args we normally pass to sphinx-build, but run sphinx-polyversion
run: |
make -C docs/ html
uv run make -C docs/ html
touch docs/_build/.nojekyll
cp docs/redirect.html docs/_build/index.html
- uses: peaceiris/actions-gh-pages@v4
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.x"
python-version-file: "pyproject.toml"

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox "ruff>=0.1.0"
uv sync --locked --extra dev
- name: Run ruff
run: ruff check --output-format=github .
run: uv run ruff check --output-format=github .
- name: Run codespell
run: tox -e codespell
run: uv run tox -e codespell
36 changes: 14 additions & 22 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,40 @@

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?="-W" "-E"
SPHINXBUILD ?= sphinx-multiversion
SPHINXBUILD = sphinx-build
POLYBUILD = sphinx-polyversion
SOURCEDIR = .
BUILDDIR ?= _build
BUILDDIR ?= docs/_build
SPHINXOPTS ?= -E -v


# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) --help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) --help "$(SOURCEDIR)" "$(BUILDDIR)" $(O)

.PHONY: help Makefile clean local news _build_local _html
.PHONY: help Makefile clean cleanall local _build_local _html

clean:
rm -rf $(BUILDDIR)/*
rm -rf $(BUILDDIR)/main
rm -rf auto_examples/
rm -rf api/generated/

cleanall: clean
rm -rf $(BUILDDIR)/*

# For local build
local:
make _build_local; STATUS=$$?; exit $$STATUS

## First build will create warnings for auto_examples. Second one will work correctly.
_build_local:
sphinx-build "$(SOURCEDIR)" "$(BUILDDIR)" "-E" $(O)
sphinx-build "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# $(POLYBUILD) ./poly.py -vv -l -o NO_PATCH=True -o OUTPUT_DIR="$(BUILDDIR)" -o SOURCE_DIR="$(SOURCEDIR)" -o TAG_REGEX="^$$"
$(SPHINXBUILD) "$(SOURCEDIR)" _build/dev $(SPHINXOPTS) $(O)

html:
make _html; STATUS=$$?; exit $$STATUS


## Build only tags that are not already built, and ignore dev tags. This is useful for CI to avoid building all tags on every push, but still build new tags when they are created.
_html:
@regex=$$( \
for tag in $$(git tag -l); do \
if [ ! -d "$(BUILDDIR)/$$tag" ]; then \
echo "$$tag"; \
fi; \
done | \
grep -v dev | \
paste -sd'|' - \
); \
echo "$$regex"; \
$(SPHINXBUILD) "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -D "smv_tag_whitelist='^($$regex)$$'" $(O)
$(POLYBUILD) ./poly.py -vv -o OUTPUT_DIR="$(BUILDDIR)" -o SOURCE_DIR="$(SOURCEDIR)"

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
126 changes: 126 additions & 0 deletions docs/_static/css/version_selector.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/* Furo-native version selector styles.
Uses furo CSS variables for full light/dark mode compatibility. */

/* ── Sidebar version selector ────────────────────────────────────────────── */

#version-selector {
border-top: 1px solid var(--color-sidebar-search-border);
padding-top: calc(var(--sidebar-item-spacing-vertical) / 2);
}

/* Remove default browser <details> marker */
.version-details > summary {
list-style: none;
}
.version-details > summary::-webkit-details-marker {
display: none;
}

/* Summary row: looks like a furo sidebar caption */
.version-summary {
cursor: pointer;
display: flex;
align-items: center;
gap: 0.4em;
padding: var(--sidebar-item-spacing-vertical)
var(--sidebar-item-spacing-horizontal);
font-size: var(--font-size--small--2);
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
color: var(--color-sidebar-caption-text);
user-select: none;
}

.version-summary:hover {
background-color: var(--color-sidebar-item-background--hover);
}

/* Chevron: points right when closed, down when open */
.version-summary::after {
content: "▶";
font-size: 0.6em;
margin-left: auto;
transition: transform 0.15s ease;
color: var(--color-sidebar-caption-text);
}

.version-details[open] > .version-summary::after {
transform: rotate(90deg);
}

/* Colored status dot */
.version-status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}

.version-status-dot--latest { background-color: #28a745; }
.version-status-dot--old { background-color: #dc3545; }
.version-status-dot--dev { background-color: #e67e00; }

/* Version list */
.version-details ul {
margin: 0;
padding: 0;
list-style: none;
}

.version-details .toctree-l1 > a {
display: block;
padding: var(--sidebar-item-spacing-vertical)
var(--sidebar-item-spacing-horizontal);
color: var(--color-sidebar-link-text);
font-size: var(--sidebar-item-font-size);
text-decoration: none;
}

.version-details .toctree-l1 > a:hover {
background-color: var(--color-sidebar-item-background--hover);
color: var(--color-sidebar-link-text--top-level);
}

.version-details .toctree-l1.current > a {
background-color: var(--color-sidebar-item-background--current, transparent);
color: var(--color-sidebar-link-text--top-level);
font-weight: bold;
}

.version-details .toctree-l1 > a em {
font-size: 0.85em;
opacity: 0.75;
}

/* ── Version banner (toc-drawer / right sidebar) ─────────────────────────── */

.version-banner {
padding: 0.6rem 0.75rem;
margin: 0.75rem 0.5rem 0;
border-radius: 0.2rem;
border-left: 3px solid;
font-size: var(--font-size--small--2);
line-height: 1.4;
}

.version-banner a {
font-weight: bold;
color: inherit;
}

.version-banner--latest {
background-color: rgba(40, 167, 69, 0.12);
border-left-color: #28a745;
}

.version-banner--old {
background-color: rgba(220, 53, 69, 0.12);
border-left-color: #dc3545;
}

.version-banner--dev {
background-color: rgba(230, 126, 0, 0.12);
border-left-color: #e67e00;
}
36 changes: 10 additions & 26 deletions docs/_templates/versions.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,11 @@
{%- if current_version %}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Other Versions</span>
v: {{ current_version.name }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
{%- if versions.tags %}
<dl>
<dt>Tags</dt>
{%- for item in versions.tags %}
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
{%- endfor %}
</dl>
{%- endif %}
{%- if versions.branches %}
<dl>
<dt>Branches</dt>
{%- for item in versions.branches %}
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
{%- endfor %}
</dl>
{%- endif %}
</div>
{# Furo-native version selector.
This placeholder is rendered by Sphinx at build time.
poly.py replaces it with the full multi-version list when patching. #}
<div id="version-selector" class="sidebar-tree version-selector">
<details class="version-details" open>
<summary class="version-summary">
<span class="version-status-dot version-status-dot--latest"></span>
<span class="caption-text">Version</span>
</summary>
</details>
</div>
{%- endif %}
Loading
Loading