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
2 changes: 1 addition & 1 deletion .copier-answers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
_commit: 162463c
_src_path: https://github.com/python-project-templates/base.git
add_docs: true
add_extension: python
add_extension: js
add_wiki: false
email: t.paine154@gmail.com
github: python-project-templates
Expand Down
14 changes: 14 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,17 @@ updates:
labels:
- "lang: python"
- "part: dependencies"

- package-ecosystem: "npm"
directory: "/js"
schedule:
interval: "monthly"
cooldown:
default-days: 7
groups:
javascript:
patterns:
- "*"
labels:
- "lang: javascript"
- "part: dependencies"
9 changes: 7 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ jobs:
with:
version: "3.11"

- name: Setup Node.js
uses: actions-ext/node/setup@03c9f6b2d9c9fa2c26cfa22d0fa379a69329b319
with:
version: 22.x

- name: Install dependencies
run: make develop

Expand All @@ -53,11 +58,11 @@ jobs:
- name: Test
run: make coverage

- name: Upload test results (Python)
- name: Upload test results
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: test-results
path: junit.xml
path: '**/junit.xml'
if: always()

- name: Publish test results
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,23 @@ jobs:
run: |
uv pip install dist/*.whl
uv pip install dist/*.whl --target . --no-deps
uv pip install "yardang[themes]"
uv pip install myst-parser
if: github.event_name == 'workflow_run'

- name: Setup Node.js (manual trigger)
uses: actions-ext/node/setup@03c9f6b2d9c9fa2c26cfa22d0fa379a69329b319
with:
version: 22.x
if: github.event_name == 'workflow_dispatch'

- name: Install from source (manual trigger)
run: |
uv pip install .[develop]
uv pip install "yardang[themes]"
uv pip install myst-parser
if: github.event_name == 'workflow_dispatch'

- name: Build documentation
run: yardang build
run: python -m sphinx -W -b html docs docs/html

- name: Publish documentation
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,5 @@ ROADMAP.md
AGENTS.md
.github/hooks/sdlc.json
.superpowers

!docs/src/index.md
100 changes: 73 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
#########
# BUILD #
#########
.PHONY: develop build install

develop: ## install dependencies and build library
.PHONY: develop-py develop-js develop
develop-py:
uv pip install -e .[develop]

requirements: ## install prerequisite python build requirements
develop-js: requirements-js

develop: develop-js develop-py ## setup project for development

.PHONY: requirements-py requirements-js requirements
requirements-py: ## install prerequisite python build requirements
uv pip install -r pyproject.toml --extra develop

build: ## build the python library
python -m build -n
requirements-js: ## install prerequisite javascript build requirements
pnpm --dir js install --frozen-lockfile
pnpm --dir js exec playwright install chromium

requirements: requirements-js requirements-py ## setup project for development

.PHONY: build-py build-js build
build-py:
python -m build -w -n

build-js:
cd js; pnpm build

install: ## install library
build: build-js build-py ## build the project

.PHONY: install
install: ## install python library
uv pip install .

#########
# LINTS #
#########
.PHONY: lint-py lint-docs fix-py fix-docs lint lints fix format

lint-py: ## lint python with ruff
.PHONY: lint-py lint-js lint lints
lint-py: ## run python linter with ruff
python -m ruff check sphinx_pele
python -m ruff format --check sphinx_pele

lint-js: ## run js linter
cd js; pnpm lint

lint-docs: ## lint docs with mdformat and codespell
python -m mdformat --check README.md $(wildcard docs/src)
python -m codespell_lib README.md $(wildcard docs/src)
python -m mdformat --check README.md docs/src
python -m codespell_lib README.md docs/src

lint: lint-js lint-py lint-docs ## run project linters

# alias
lints: lint

fix-py: ## autoformat python code with ruff
.PHONY: fix-py fix-js fix-docs fix format
fix-py: ## fix python formatting with ruff
python -m ruff check --fix sphinx_pele
python -m ruff format sphinx_pele

fix-js: ## fix js formatting
cd js; pnpm fix

fix-docs: ## autoformat docs with mdformat and codespell
python -m mdformat README.md $(wildcard docs/src)
python -m codespell_lib --write README.md $(wildcard docs/src)
python -m mdformat README.md docs/src
python -m codespell_lib --write README.md docs/src

lint: lint-py lint-docs ## run all linters
lints: lint
fix: fix-py fix-docs ## run all autoformatters
fix: fix-js fix-py fix-docs ## run project autoformatters

# alias
format: fix

################
Expand All @@ -54,21 +82,36 @@ check-types: ## check python types with ty

checks: check-dist check-types

# Alias
# alias
check: checks

#########
# TESTS #
#########
.PHONY: test coverage tests

test: ## run python tests
.PHONY: test-py tests-py coverage-py
test-py: ## run python tests
python -m pytest -v sphinx_pele/tests

coverage: ## run tests and collect test coverage
# alias
tests-py: test-py

coverage-py: ## run python tests and collect test coverage
python -m pytest -v sphinx_pele/tests --cov=sphinx_pele --cov-report term-missing --cov-report xml

# Alias
.PHONY: test-js tests-js coverage-js
test-js: ## run js tests
cd js; pnpm test

# alias
tests-js: test-js

coverage-js: test-js ## run js tests and collect test coverage

.PHONY: test coverage tests
test: test-py test-js ## run all tests
coverage: coverage-py coverage-js ## run all tests and collect test coverage

# alias
tests: test

###########
Expand All @@ -91,15 +134,18 @@ major: ## bump a major version
########
# DIST #
########
.PHONY: dist dist-build dist-sdist dist-local-wheel publish
.PHONY: dist dist-py dist-js dist-check publish

dist-build: # build python dists
dist-py: ## build python dists
python -m build -w -s

dist-js: # build js dists
cd js; pnpm pack

dist-check: ## run python dist checker with twine
python -m twine check dist/*

dist: clean dist-build dist-check ## build all dists
dist: clean build dist-py dist-check ## build all dists

publish: dist ## publish python assets

Expand Down
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,33 @@ Pele mermaid diagrams for Sphinx
[![License](https://img.shields.io/github/license/python-project-templates/sphinx-pele)](https://github.com/python-project-templates/sphinx-pele)
[![PyPI](https://img.shields.io/pypi/v/sphinx-pele.svg)](https://pypi.python.org/pypi/sphinx-pele)

## Overview
## Usage

> [!NOTE]
> This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
Install and enable the extension:

```sh
pip install sphinx-pele
```

```python
# conf.py
extensions = ["sphinx_pele"]
pele_options = {"zoom": "auto"}
```

```rst
.. mermaid::

flowchart LR
Mermaid --> Pele --> SVG
```

MyST Markdown `mermaid` fences and external `.mmd` files also work. Replace
`sphinxcontrib.mermaid` in `extensions` when migrating.

See [usage](docs/src/usage.md), [configuration](docs/src/configuration.md), and
[examples](docs/src/examples.md). HTML uses bundled Pele assets. Other builders
retain Mermaid source.

-> [!NOTE]
-> This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
10 changes: 10 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
extensions = ["myst_parser", "sphinx_pele"]
project = "sphinx-pele"
root_doc = "src/index"
exclude_patterns = ["_build"]
html_theme = "alabaster"
pele_options = {"zoom": False}
97 changes: 97 additions & 0 deletions docs/src/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Configuration reference

## Sphinx settings

| Setting | Default | Meaning |
| -------------------- | ------- | ------------------------------------------------------------------- |
| `pele_options` | `{}` | JSON-compatible Pele mount options, using upstream camelCase names. |
| `pele_css_variables` | `{}` | CSS custom properties with `--pele-` names and string values. |

Pele 1.6.0 is bundled in the wheel. HTML documentation uses local JavaScript and
CSS, with no CDN or Node.js runtime requirement. Building the package from source
requires Node.js and pnpm.

## Diagram configuration

The `pele` mapping in **diagram** YAML frontmatter accepts the same options as
`pele_options`, plus `cssVariables`. It is not document-level MyST frontmatter.
The source, including Mermaid `title`, `config`, and `%%{init: ...}%%` directives,
is passed to Pele unchanged.

Option precedence, lowest to highest:

1. `pele_options` in `conf.py`.
1. Diagram frontmatter's `pele` mapping.
1. Directive `:options:` mapping.
1. Directive `:zoom:` and `:config:` values.

Nested mappings merge recursively; lists and scalar values replace earlier values.
Mermaid's native frontmatter and initialization directives override defaults in
`options.config` according to Pele's parser. CSS variables merge from Sphinx
settings and diagram `pele.cssVariables`.

## Render options

The extension accepts these JSON-compatible [Pele options](https://pele.run/api):

| Options | Type |
| -------------------------------------------------------- | ---------------------------------------- |
| `fontFamily`, `fontFamilyMono`, `idPrefix`, `linkRel` | String |
| `fontSize`, `maxWidth`, `directionBreakpoint`, `padding` | Number |
| `now` | Numeric Unix timestamp in milliseconds |
| `limit`, `outputLimit`, `maxEdges` | Number |
| `responsive`, `autoDirection`, `links`, `images` | Boolean |
| `linkSchemes`, `imageSchemes` | List of strings |
| `config` | Mermaid configuration mapping |
| `zoom` | Boolean, `auto`, or zoom options mapping |

Zoom mappings accept Pele's `always`, `maxScale`, `controls`, and `labels` options.
Pele supplies defaults for omitted values. Mounting measures the container width;
`:width:` controls the container's available width. `maxWidth` is accepted for API
compatibility but Pele's mount operation uses the measured width.

Function-valued options (`measurer`, `icons`, `sanitize`, `onRender`, `onError`)
are not serialized from Python or YAML. Diagram authors have control over the
exposed rendering options, including links, image URLs, and resource limits;
frontmatter is intended for trusted documentation sources.

Unknown option names, invalid top-level types, and non-JSON values produce build
errors for Sphinx settings or `pele.config` warnings for diagrams. `sphinx-build -W` makes warnings fail the build. Mermaid syntax errors are displayed by Pele
in the browser; they are not validated during the Sphinx build.

## Directives

`mermaid` and `pele` are aliases. Both accept inline Mermaid or one filename,
but not both. Files are UTF-8 and tracked as Sphinx build dependencies. Paths
starting with `/` are relative to Sphinx's source directory.

| Option | Meaning |
| ----------------- | --------------------------------------------------------------------------------------- |
| `name` | Sphinx reference target; targets the figure when a caption is present. |
| `class` | Additional container classes. |
| `caption` | Figure caption with inline markup. |
| `alt` | Accessible container label. |
| `align` | `left`, `center`, or `right`. |
| `width`, `height` | Container dimensions; unitless values mean pixels. Width accepts percentages. |
| `title` | Visible heading above the diagram. Native Mermaid frontmatter titles remain in the SVG. |
| `zoom` | YAML boolean, `auto`, or mapping; an empty option enables zoom. |
| `options` | YAML/JSON mapping of render options. |
| `config` | YAML/JSON mapping of default Mermaid settings. |

Ordinary `mermaid` and `pele` code blocks also render as diagrams. This includes
MyST fences, `{code-block}` directives, and reStructuredText `code-block`
directives. No MyST fence registration is needed.

## Themes and builders

The stylesheet reads Furo and PyData theme variables for diagram colors. Other
themes use light defaults. Any [Pele CSS variable](https://pele.run/theming) can
be set through `pele_css_variables`, diagram `cssVariables`, or a custom
stylesheet registered with Sphinx's `html_css_files`. CSS values may refer to
theme variables, so changing theme colors does not require rendering again.

HTML-family builders render SVG in the browser, including responsive layout and
Pele zoom controls. Without JavaScript, escaped Mermaid source remains visible.
Text, LaTeX, man, and other non-HTML builders emit source as a literal block;
PDF/image export is not implemented. Mermaid CLI options, D3 zoom, and
`sphinxcontrib.mermaid`'s class-tree generator are not supported.
Loading