Rebuild sphinx scaffold on `pydata` theme
Full `docs/conf.py` rewrite targeting `pydata-sphinx-theme` 0.18 (3-col layout: nav-index left, content middle, page-toc right) skinned to a minimal b&w look via `_static/css/custom.css`, keeping the `algol_nu` pygments style. Also add 2 local sphinx exts under `docs/_ext/`, - `d2diagrams.py`: a `.. d2::` directive rendering `d2lang` sources at build time when a `d2` bin is found (`D2_BIN` env supports argful values eg. `'nix run nixpkgs#d2 --'`), falling back to any git-committed SVG, else emitting the raw source as a literal block; no pypi ext was usable (all stubs or returncode-swallowing per the #157 research), - `marginalia.py`: a theme-agnostic `.. margin::` directive (`sphinx-book-theme` style `Sidebar` subclass) for prose-anchored RHS asides; the custom css floats these (and `:margin:` d2 figs) into the right gutter on wide screens. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
parent
1c12acaf1d
commit
ca7cc1a1a1
|
|
@ -0,0 +1,235 @@
|
||||||
|
# tractor: distributed structured concurrency.
|
||||||
|
'''
|
||||||
|
``.. d2::`` - embed d2lang_ diagrams in sphinx docs
|
||||||
|
with build-time rendering and a committed-SVG
|
||||||
|
fallback.
|
||||||
|
|
||||||
|
Rendering policy,
|
||||||
|
|
||||||
|
- when a ``d2`` binary is found (see discovery order
|
||||||
|
below) any out-of-date SVG is (re)rendered from its
|
||||||
|
``.d2`` source (normally kept in ``docs/diagrams/``)
|
||||||
|
into ``docs/_diagrams/``,
|
||||||
|
- otherwise any pre-rendered (and git committed) SVG
|
||||||
|
already in ``docs/_diagrams/`` is used as-is,
|
||||||
|
- when neither is possible the diagram *source* is
|
||||||
|
emitted as a literal block so no content is ever
|
||||||
|
silently dropped.
|
||||||
|
|
||||||
|
Binary discovery order,
|
||||||
|
|
||||||
|
- the ``D2_BIN`` env var; may contain args which are
|
||||||
|
split via `shlex`, eg.
|
||||||
|
``D2_BIN='nix run nixpkgs#d2 --'``,
|
||||||
|
- the ``d2_bin`` sphinx config value,
|
||||||
|
- ``shutil.which('d2')``.
|
||||||
|
|
||||||
|
Usage,
|
||||||
|
|
||||||
|
.. code:: rst
|
||||||
|
|
||||||
|
.. d2:: diagrams/actor_tree.d2
|
||||||
|
:caption: A tree of ``trio``-task-trees.
|
||||||
|
:margin:
|
||||||
|
|
||||||
|
.. _d2lang: https://d2lang.com
|
||||||
|
|
||||||
|
'''
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
import subprocess as sp
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst import directives
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
from sphinx.util import logging
|
||||||
|
from sphinx.util.docutils import SphinxDirective
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# subdir (under the sphinx srcdir) holding rendered,
|
||||||
|
# git-committed, fallback SVG outputs.
|
||||||
|
_outdir: str = '_diagrams'
|
||||||
|
|
||||||
|
|
||||||
|
def find_d2(
|
||||||
|
app: Sphinx,
|
||||||
|
) -> list[str]|None:
|
||||||
|
'''
|
||||||
|
Resolve the d2 render command as an argv list or
|
||||||
|
`None` when no binary can be found.
|
||||||
|
|
||||||
|
'''
|
||||||
|
if env_bin := os.environ.get('D2_BIN'):
|
||||||
|
return shlex.split(env_bin)
|
||||||
|
if cfg_bin := app.config.d2_bin:
|
||||||
|
return shlex.split(cfg_bin)
|
||||||
|
if path_bin := shutil.which('d2'):
|
||||||
|
return [path_bin]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def render_svg(
|
||||||
|
app: Sphinx,
|
||||||
|
src: Path,
|
||||||
|
out: Path,
|
||||||
|
) -> bool:
|
||||||
|
'''
|
||||||
|
Maybe (re)render `src` -> `out`, returning
|
||||||
|
`True` when an up-to-date SVG exists after the
|
||||||
|
call.
|
||||||
|
|
||||||
|
'''
|
||||||
|
stale: bool = (
|
||||||
|
not out.exists()
|
||||||
|
or
|
||||||
|
src.stat().st_mtime > out.stat().st_mtime
|
||||||
|
)
|
||||||
|
if not stale:
|
||||||
|
return True
|
||||||
|
d2cmd: list[str]|None = find_d2(app)
|
||||||
|
if d2cmd is None:
|
||||||
|
if out.exists():
|
||||||
|
log.info(
|
||||||
|
f'no d2 binary; using committed svg '
|
||||||
|
f'for {src.name}'
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
out.parent.mkdir(
|
||||||
|
parents=True,
|
||||||
|
exist_ok=True,
|
||||||
|
)
|
||||||
|
argv: list[str] = (
|
||||||
|
d2cmd
|
||||||
|
+ list(app.config.d2_args)
|
||||||
|
+ [str(src), str(out)]
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
proc = sp.run(
|
||||||
|
argv,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=120,
|
||||||
|
)
|
||||||
|
except (
|
||||||
|
OSError,
|
||||||
|
sp.TimeoutExpired,
|
||||||
|
) as err:
|
||||||
|
log.warning(
|
||||||
|
f'd2 invocation failed for {src.name}: '
|
||||||
|
f'{err}'
|
||||||
|
)
|
||||||
|
return out.exists()
|
||||||
|
if proc.returncode != 0:
|
||||||
|
log.warning(
|
||||||
|
f'd2 render error for {src.name}:\n'
|
||||||
|
f'{proc.stderr}'
|
||||||
|
)
|
||||||
|
return out.exists()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class D2Diagram(SphinxDirective):
|
||||||
|
'''
|
||||||
|
Render a ``.d2`` source file (path relative to
|
||||||
|
the sphinx srcdir) as an SVG figure.
|
||||||
|
|
||||||
|
'''
|
||||||
|
required_arguments = 1
|
||||||
|
has_content = False
|
||||||
|
option_spec = {
|
||||||
|
'caption': directives.unchanged,
|
||||||
|
'alt': directives.unchanged,
|
||||||
|
'width': (
|
||||||
|
directives.length_or_percentage_or_unitless
|
||||||
|
),
|
||||||
|
'margin': directives.flag,
|
||||||
|
'class': directives.class_option,
|
||||||
|
'name': directives.unchanged,
|
||||||
|
}
|
||||||
|
|
||||||
|
def run(self) -> list[nodes.Node]:
|
||||||
|
relsrc: str = self.arguments[0]
|
||||||
|
srcdir = Path(self.env.srcdir)
|
||||||
|
src: Path = srcdir / relsrc
|
||||||
|
self.env.note_dependency(relsrc)
|
||||||
|
if not src.exists():
|
||||||
|
err = self.state_machine.reporter.error(
|
||||||
|
f'd2 source not found: {relsrc}',
|
||||||
|
line=self.lineno,
|
||||||
|
)
|
||||||
|
return [err]
|
||||||
|
out: Path = (
|
||||||
|
srcdir
|
||||||
|
/ _outdir
|
||||||
|
/ f'{src.stem}.svg'
|
||||||
|
)
|
||||||
|
if not render_svg(self.env.app, src, out):
|
||||||
|
# last resort: emit the raw d2 source.
|
||||||
|
log.warning(
|
||||||
|
f'no svg available for {relsrc}; '
|
||||||
|
f'emitting d2 source as literal block'
|
||||||
|
)
|
||||||
|
literal = nodes.literal_block(
|
||||||
|
src.read_text(),
|
||||||
|
src.read_text(),
|
||||||
|
)
|
||||||
|
literal['language'] = 'text'
|
||||||
|
return [literal]
|
||||||
|
img = nodes.image(
|
||||||
|
uri=f'/{_outdir}/{out.name}',
|
||||||
|
alt=self.options.get(
|
||||||
|
'alt',
|
||||||
|
f'd2 diagram: {src.stem}',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if width := self.options.get('width'):
|
||||||
|
img['width'] = width
|
||||||
|
fig = nodes.figure()
|
||||||
|
fig += img
|
||||||
|
classes: list[str] = (
|
||||||
|
['d2-diagram']
|
||||||
|
+ self.options.get('class', [])
|
||||||
|
)
|
||||||
|
if 'margin' in self.options:
|
||||||
|
# NB: the bare 'margin' class is what
|
||||||
|
# book-style themes key off for
|
||||||
|
# right-margin placement; our custom css
|
||||||
|
# uses 'd2-margin'.
|
||||||
|
classes += [
|
||||||
|
'margin',
|
||||||
|
'd2-margin',
|
||||||
|
]
|
||||||
|
fig['classes'] += classes
|
||||||
|
if caption_txt := self.options.get('caption'):
|
||||||
|
(
|
||||||
|
inline_nodes,
|
||||||
|
_msgs,
|
||||||
|
) = self.state.inline_text(
|
||||||
|
caption_txt,
|
||||||
|
self.lineno,
|
||||||
|
)
|
||||||
|
caption = nodes.caption(
|
||||||
|
caption_txt,
|
||||||
|
'',
|
||||||
|
*inline_nodes,
|
||||||
|
)
|
||||||
|
fig += caption
|
||||||
|
self.add_name(fig)
|
||||||
|
return [fig]
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app: Sphinx) -> dict:
|
||||||
|
app.add_config_value('d2_bin', None, 'env')
|
||||||
|
app.add_config_value('d2_args', [], 'env')
|
||||||
|
app.add_directive('d2', D2Diagram)
|
||||||
|
return {
|
||||||
|
'version': '0.1.0',
|
||||||
|
'parallel_read_safe': True,
|
||||||
|
'parallel_write_safe': True,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
# tractor: distributed structured concurrency.
|
||||||
|
'''
|
||||||
|
``.. margin::`` - prose-anchored, right-margin asides.
|
||||||
|
|
||||||
|
A theme-agnostic vendoring of `sphinx_book_theme`'s
|
||||||
|
`Margin` directive: a `docutils` `Sidebar` subclass
|
||||||
|
which tags the node with a ``margin`` class; placement
|
||||||
|
is then pure CSS (see ``_static/css/custom.css``)
|
||||||
|
allowing use on any theme incl. our
|
||||||
|
`pydata_sphinx_theme`.
|
||||||
|
|
||||||
|
Usage,
|
||||||
|
|
||||||
|
.. code:: rst
|
||||||
|
|
||||||
|
.. margin:: An optional title
|
||||||
|
|
||||||
|
Aside content; text, figures, whatever.
|
||||||
|
|
||||||
|
'''
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst.directives.body import (
|
||||||
|
Sidebar,
|
||||||
|
)
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
|
||||||
|
|
||||||
|
class Margin(Sidebar):
|
||||||
|
'''
|
||||||
|
Notes/figures placed in the right margin, anchored
|
||||||
|
at the current point in the prose flow.
|
||||||
|
|
||||||
|
'''
|
||||||
|
required_arguments = 0
|
||||||
|
optional_arguments = 1
|
||||||
|
|
||||||
|
def run(self) -> list[nodes.Node]:
|
||||||
|
if not self.arguments:
|
||||||
|
self.arguments = ['']
|
||||||
|
out: list[nodes.Node] = super().run()
|
||||||
|
out[0].attributes['classes'].append('margin')
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app: Sphinx) -> dict:
|
||||||
|
app.add_directive('margin', Margin)
|
||||||
|
return {
|
||||||
|
'version': '0.1.0',
|
||||||
|
'parallel_read_safe': True,
|
||||||
|
'parallel_write_safe': True,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* tractor docs: a minimal black + white skin over
|
||||||
|
* `pydata-sphinx-theme` plus RHS-marginalia + d2
|
||||||
|
* diagram styling.
|
||||||
|
*/
|
||||||
|
html[data-theme="light"] {
|
||||||
|
--pst-color-primary: #000000;
|
||||||
|
--pst-color-secondary: #3d3d3d;
|
||||||
|
--pst-color-accent: #5a5a5a;
|
||||||
|
--pst-color-link: #000000;
|
||||||
|
--pst-color-link-hover: #5a5a5a;
|
||||||
|
--pst-color-inline-code: #1a1a1a;
|
||||||
|
--pst-color-inline-code-links: #000000;
|
||||||
|
}
|
||||||
|
html[data-theme="dark"] {
|
||||||
|
--pst-color-primary: #ffffff;
|
||||||
|
--pst-color-secondary: #c9c9c9;
|
||||||
|
--pst-color-accent: #a8a8a8;
|
||||||
|
--pst-color-link: #ffffff;
|
||||||
|
--pst-color-link-hover: #bdbdbd;
|
||||||
|
--pst-color-inline-code: #e8e8e8;
|
||||||
|
--pst-color-inline-code-links: #ffffff;
|
||||||
|
}
|
||||||
|
/* mono-chrome links: rely on underline for
|
||||||
|
* affordance instead of color.
|
||||||
|
*/
|
||||||
|
.bd-content a:not(.headerlink) {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 0.18em;
|
||||||
|
}
|
||||||
|
/* d2 diagram figures */
|
||||||
|
figure.d2-diagram {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
figure.d2-diagram img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
/* keep light-rendered svgs legible in dark mode */
|
||||||
|
html[data-theme="dark"] figure.d2-diagram img {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
/* prose-anchored right-margin asides (tufte-ish):
|
||||||
|
* float right within the content column on wide
|
||||||
|
* screens, collapse inline on narrow ones.
|
||||||
|
*/
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
aside.margin,
|
||||||
|
figure.margin,
|
||||||
|
div.margin,
|
||||||
|
figure.d2-margin {
|
||||||
|
float: right;
|
||||||
|
clear: right;
|
||||||
|
width: 44%;
|
||||||
|
margin: 0.2rem 0 1rem 1.4rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* strip docutils sidebar chrome from margin asides */
|
||||||
|
aside.sidebar.margin {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
aside.sidebar.margin > p.sidebar-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
/* landing page hero logo sizing */
|
||||||
|
img.hero-logo {
|
||||||
|
max-width: 360px;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
198
docs/conf.py
198
docs/conf.py
|
|
@ -1,105 +1,147 @@
|
||||||
# Configuration file for the Sphinx documentation builder.
|
# tractor: distributed structured concurrency.
|
||||||
#
|
'''
|
||||||
# This file only contains a selection of the most common options. For a full
|
Sphinx config for `tractor`'s documentation.
|
||||||
# list see the documentation:
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
||||||
|
|
||||||
# -- Path setup --------------------------------------------------------------
|
Theme-wise we ride the `pydata_sphinx_theme` (per the
|
||||||
|
research + history in #157) skinned to a minimal
|
||||||
|
black + white look via `_static/css/custom.css`; see
|
||||||
|
the local extensions under `_ext/` for our `.. d2::`
|
||||||
|
diagram and `.. margin::` aside directives.
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
Build locally via,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#
|
|
||||||
# import os
|
|
||||||
# import sys
|
|
||||||
# sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# Warn about all references to unknown targets
|
uv run --group docs make -C docs html
|
||||||
nitpicky = True
|
|
||||||
|
|
||||||
# The master toctree document.
|
'''
|
||||||
master_doc = 'index'
|
from importlib.metadata import version as get_version
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# local sphinx extensions live in `_ext/`:
|
||||||
|
# - `d2diagrams`: `.. d2::` diagram rendering
|
||||||
|
# - `marginalia`: `.. margin::` RHS prose-asides
|
||||||
|
sys.path.insert(
|
||||||
|
0,
|
||||||
|
str((Path(__file__).parent / '_ext').resolve()),
|
||||||
|
)
|
||||||
|
|
||||||
|
# -- project info ---------------------------------
|
||||||
|
|
||||||
project = 'tractor'
|
project = 'tractor'
|
||||||
copyright = '2018, Tyler Goodlet'
|
copyright = '2018-2026, Tyler Goodlet'
|
||||||
author = 'Tyler Goodlet'
|
author = 'Tyler Goodlet'
|
||||||
|
release: str = get_version('tractor')
|
||||||
|
version: str = release
|
||||||
|
|
||||||
# The full version, including alpha/beta/rc tags
|
# -- general config -------------------------------
|
||||||
release = '0.0.0a0.dev0'
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
extensions = [
|
||||||
'sphinx.ext.autodoc',
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.autosummary',
|
||||||
'sphinx.ext.intersphinx',
|
'sphinx.ext.intersphinx',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
'sphinx.ext.todo',
|
'sphinx.ext.todo',
|
||||||
|
'sphinx_design',
|
||||||
|
'sphinx_copybutton',
|
||||||
|
'sphinxext.opengraph',
|
||||||
|
'sphinx_togglebutton',
|
||||||
|
'd2diagrams',
|
||||||
|
'marginalia',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
exclude_patterns = [
|
||||||
|
'_build',
|
||||||
|
# the pypi/gh readme + its standalone generator
|
||||||
|
# sub-project; NOT doc-tree pages.
|
||||||
|
'README.rst',
|
||||||
|
'github_readme',
|
||||||
|
'Thumbs.db',
|
||||||
|
'.DS_Store',
|
||||||
|
]
|
||||||
|
root_doc = 'index'
|
||||||
|
# TODO: flip this on + burn down the (many) warnings
|
||||||
|
# from our informal docstring style; see the autodoc
|
||||||
|
# readiness notes from the revamp's recon pass.
|
||||||
|
nitpicky = False
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# -- autodoc/autosummary --------------------------
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
||||||
|
|
||||||
|
autodoc_member_order = 'bysource'
|
||||||
|
autodoc_typehints = 'description'
|
||||||
|
autosummary_generate = True
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
# -- intersphinx ----------------------------------
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
intersphinx_mapping = {
|
||||||
# a list of builtin themes.
|
'python': (
|
||||||
#
|
'https://docs.python.org/3',
|
||||||
html_theme = 'sphinx_book_theme'
|
None,
|
||||||
|
),
|
||||||
pygments_style = 'algol_nu'
|
'trio': (
|
||||||
|
'https://trio.readthedocs.io/en/stable',
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
None,
|
||||||
# further. For a list of options available for each theme, see the
|
),
|
||||||
# documentation.
|
# NOTE, msgspec's site doesn't publish an
|
||||||
html_theme_options = {
|
# `objects.inv` (404s) so no intersphinx for it.
|
||||||
# 'logo': 'tractor_logo_side.svg',
|
'pytest': (
|
||||||
# 'description': 'Structured concurrent "actors"',
|
'https://docs.pytest.org/en/stable',
|
||||||
"repository_url": "https://github.com/goodboy/tractor",
|
None,
|
||||||
"use_repository_button": True,
|
),
|
||||||
"home_page_in_toc": False,
|
|
||||||
"show_toc_level": 1,
|
|
||||||
"path_to_docs": "docs",
|
|
||||||
|
|
||||||
}
|
|
||||||
html_sidebars = {
|
|
||||||
"**": [
|
|
||||||
"sbt-sidebar-nav.html",
|
|
||||||
# "sidebar-search-bs.html",
|
|
||||||
# 'localtoc.html',
|
|
||||||
],
|
|
||||||
# 'logo.html',
|
|
||||||
# 'github.html',
|
|
||||||
# 'relations.html',
|
|
||||||
# 'searchbox.html'
|
|
||||||
# ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# doesn't seem to work?
|
# -- html output ----------------------------------
|
||||||
# extra_navbar = "<p>nextttt-gennnnn</p>"
|
|
||||||
|
|
||||||
html_title = ''
|
html_theme = 'pydata_sphinx_theme'
|
||||||
|
html_title = 'tractor'
|
||||||
html_logo = '_static/tractor_logo_side.svg'
|
html_logo = '_static/tractor_logo_side.svg'
|
||||||
html_favicon = '_static/tractor_logo_side.svg'
|
html_favicon = '_static/tractor_logo_side.svg'
|
||||||
# show_navbar_depth = 1
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
html_static_path = ['_static']
|
||||||
|
html_css_files = ['css/custom.css']
|
||||||
# Example configuration for intersphinx: refer to the Python standard library.
|
html_show_sourcelink = False
|
||||||
intersphinx_mapping = {
|
html_theme_options = {
|
||||||
"python": ("https://docs.python.org/3", None),
|
'logo': {
|
||||||
"pytest": ("https://docs.pytest.org/en/latest", None),
|
'image_light': '_static/tractor_logo_side.svg',
|
||||||
"setuptools": ("https://setuptools.readthedocs.io/en/latest", None),
|
'image_dark': '_static/tractor_logo_side.svg',
|
||||||
|
'alt_text': 'tractor',
|
||||||
|
},
|
||||||
|
'github_url': 'https://github.com/goodboy/tractor',
|
||||||
|
'navbar_align': 'content',
|
||||||
|
'show_toc_level': 2,
|
||||||
|
'secondary_sidebar_items': {
|
||||||
|
'**': ['page-toc'],
|
||||||
|
'index': [],
|
||||||
|
},
|
||||||
|
'use_edit_page_button': True,
|
||||||
|
'footer_start': ['copyright'],
|
||||||
|
'footer_end': ['theme-version'],
|
||||||
|
'pygments_light_style': 'algol_nu',
|
||||||
|
'pygments_dark_style': 'github-dark',
|
||||||
}
|
}
|
||||||
|
html_context = {
|
||||||
|
'github_user': 'goodboy',
|
||||||
|
'github_repo': 'tractor',
|
||||||
|
'github_version': 'main',
|
||||||
|
'doc_path': 'docs',
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- ext: opengraph -------------------------------
|
||||||
|
|
||||||
|
ogp_site_url = 'https://goodboy.github.io/tractor/'
|
||||||
|
ogp_use_first_image = True
|
||||||
|
|
||||||
|
# -- ext: copybutton ------------------------------
|
||||||
|
|
||||||
|
copybutton_prompt_text = r'>>> |\.\.\. |\$ '
|
||||||
|
copybutton_prompt_is_regexp = True
|
||||||
|
|
||||||
|
# -- ext: todo ------------------------------------
|
||||||
|
|
||||||
|
todo_include_todos = True
|
||||||
|
|
||||||
|
# -- ext: d2diagrams (local) ----------------------
|
||||||
|
|
||||||
|
# normally resolved from PATH or the `D2_BIN` env
|
||||||
|
# var; when neither hits, the committed SVGs under
|
||||||
|
# `_diagrams/` are used as-is.
|
||||||
|
d2_bin = None
|
||||||
|
d2_args = []
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue