sphinx_spack_lite Extension¶
The sphinx_spack_lite Python package is a Sphinx extension that brings the
spack-lite interactive terminal to any Sphinx documentation site. It adds a
:runnable: option to the standard code-block directive; marked blocks
gain a ▶ Run button that lazily initialises the spack-lite Web Worker and
streams output inline — with zero impact on page-load time for readers who do
not click.
Installation¶
The extension lives in the spack-lite repository and can be installed directly from GitHub:
$ pip install git+https://github.com/wdconinc/spack-lite.git
Or, if you have cloned the repository locally:
$ pip install -e /path/to/spack-lite
Configuration¶
Add "sphinx_spack_lite" to your conf.py extension list and set
spack_lite_base_url to the URL prefix where worker.js,
spack-lite.tar.gz, and spack-packages.tar.gz are served:
# conf.py
extensions = [
...,
"sphinx_spack_lite",
]
# URL prefix where spack-lite assets are hosted.
# Must end with '/'. Defaults to "_static/" (bundle into docs build).
# For ReadTheDocs, point to a GitHub Releases URL to avoid bloating
# the docs build with large binary tarballs.
spack_lite_base_url = "https://wdconinc.github.io/spack-lite/"
How it works¶
Build time —
RunnableCodeBlockwraps the highlighted code block in a<div data-spack-runnable="true" data-spack-commands="…">container. The commands string is the prompt-stripped text embedded as an HTML attribute.Page load —
spack_run.jsis added to every page that contains at least one runnable block (via Sphinx’sapp.add_js_filewithloading_method="defer"). OnDOMContentLoadedit scans for[data-spack-runnable]elements and injects ▶ Run buttons and output<pre>elements — but does not start the worker.First click — the worker is created with
new Worker(workerUrl). A{ type: 'configure', … }message is posted immediately so the worker uses the correct asset URLs. A loading indicator appears on the button.Execution — subsequent clicks (or the first click once the worker is ready) post
{ type: 'run', command }to the worker.stdoutchunks stream into the inline output area in real time; aresultmessage marks the block as done.Shared environment — the same worker handles all blocks on the page, so a
cdorspack installin one block affects subsequent blocks.
ReadTheDocs notes¶
ReadTheDocs does not currently support setting custom
Cross-Origin-Opener-Policy / Cross-Origin-Embedder-Policy HTTP headers,
which are required to enable SharedArrayBuffer. Pyodide can run without
SharedArrayBuffer — only the Ctrl-C interrupt feature is degraded. Basic
command execution is unaffected.
For spack_lite_base_url, point to a GitHub Releases download URL rather
than bundling the binary tarballs into the docs build:
spack_lite_base_url = (
"https://github.com/wdconinc/spack-lite/releases/latest/download/"
)
You will need to create a GitHub Release containing spack-lite.tar.gz and
spack-packages.tar.gz as release assets.
Extension API reference¶
sphinx_spack_lite¶
A Sphinx extension that integrates spack-lite (the browser-based Spack REPL) into Sphinx documentation.
Usage¶
In conf.py:
extensions = [
...,
"sphinx_spack_lite",
]
# URL prefix where worker.js, shim_system.py, shell.py,
# spack-lite.tar.gz and spack-packages.tar.gz are served.
# Default is "_static/" (i.e., they are bundled into the docs build).
# For ReadTheDocs you may want to point this at a GitHub Release URL
# to avoid bloating the docs build with large binary tarballs.
spack_lite_base_url = "https://github.com/your-org/spack-lite/releases/latest/download/"
In getting_started.rst:
.. code-block:: console
:runnable:
$ spack list
Notes¶
The Web Worker (
worker.js) is initialised lazily: nothing loads until the user clicks the first “Run ▶” button on a page.The worker is shared across all runnable blocks on a page, so the Spack environment (installed packages, cwd, etc.) persists between block runs.
SharedArrayBuffer-based interrupt (Ctrl-C) is unavailable on ReadTheDocs because it requires COOP/COEP HTTP headers that RTD does not support. Basic command execution is unaffected.
sphinx_spack_lite._directives¶
Patches Sphinx’s built-in code-block directive to recognise a
:runnable: flag. When set, the generated code block is wrapped in a
spack_run_container node whose HTML visitor emits a <div> with
data-spack-runnable and data-spack-commands attributes. The JS
layer (spack_run.js) scans for those attributes to inject “Run” buttons.
The commands string is built by stripping the shell prompt prefix
(lines starting with $) from every line that begins with it;
continuation lines (output, comments)
are ignored. The result is a JSON-encoded list of bare commands.
- class sphinx_spack_lite._directives.RunnableCodeBlock(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)¶
code-blocksubclass that adds the:runnable:boolean option.- option_spec = {'caption': <function unchanged_required>, 'class': <function class_option>, 'dedent': <function optional_int>, 'emphasize-lines': <function unchanged_required>, 'force': <function flag>, 'lineno-start': <class 'int'>, 'linenos': <function flag>, 'name': <function unchanged>, 'runnable': <function RunnableCodeBlock.<lambda>>}¶
Mapping of option names to validator functions.
- sphinx_spack_lite._directives._extract_commands(source: str) str¶
Return a JSON array of bare shell commands from a console block.
Only lines beginning with a shell prompt (
$) are treated as command lines; all other lines (output, blank lines, comments) are dropped.The result is a JSON-encoded list so that it survives round-trip through an HTML attribute value (HTML parsers normalise raw newlines in attributes to spaces, which would corrupt a newline-joined string).
- class sphinx_spack_lite._directives.spack_run_container(rawsource: str = '', *children, **attributes: Any)¶
Wrapper node that carries spack-lite execution metadata as HTML data attrs.