marimo-book 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- marimo_book-0.1.0a1/.github/workflows/ci.yml +92 -0
- marimo_book-0.1.0a1/.github/workflows/docs.yml +50 -0
- marimo_book-0.1.0a1/.github/workflows/publish.yml +53 -0
- marimo_book-0.1.0a1/.gitignore +48 -0
- marimo_book-0.1.0a1/CHANGELOG.md +87 -0
- marimo_book-0.1.0a1/LICENSE +21 -0
- marimo_book-0.1.0a1/PKG-INFO +281 -0
- marimo_book-0.1.0a1/PUBLISHING.md +135 -0
- marimo_book-0.1.0a1/README.md +237 -0
- marimo_book-0.1.0a1/docs/book.yml +55 -0
- marimo_book-0.1.0a1/docs/content/authoring.md +133 -0
- marimo_book-0.1.0a1/docs/content/book_yml.md +174 -0
- marimo_book-0.1.0a1/docs/content/dependencies.md +108 -0
- marimo_book-0.1.0a1/docs/content/deploying.md +78 -0
- marimo_book-0.1.0a1/docs/content/example.py +95 -0
- marimo_book-0.1.0a1/docs/content/index.md +77 -0
- marimo_book-0.1.0a1/docs/content/inspiration.md +103 -0
- marimo_book-0.1.0a1/docs/content/link_checks.md +81 -0
- marimo_book-0.1.0a1/docs/content/quickstart.md +77 -0
- marimo_book-0.1.0a1/docs/content/roadmap.md +145 -0
- marimo_book-0.1.0a1/docs/content/widgets.md +104 -0
- marimo_book-0.1.0a1/pyproject.toml +99 -0
- marimo_book-0.1.0a1/src/marimo_book/__init__.py +3 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/extra.css +66 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/marimo_book.js +131 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/mathjax.js +19 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/.github/workflows/deploy.yml +51 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/.gitignore +20 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/README.md +28 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/book.yml +47 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/content/example.py +54 -0
- marimo_book-0.1.0a1/src/marimo_book/assets/scaffold/content/intro.md +32 -0
- marimo_book-0.1.0a1/src/marimo_book/cli.py +382 -0
- marimo_book-0.1.0a1/src/marimo_book/config.py +276 -0
- marimo_book-0.1.0a1/src/marimo_book/launch_buttons.py +121 -0
- marimo_book-0.1.0a1/src/marimo_book/preprocessor.py +268 -0
- marimo_book-0.1.0a1/src/marimo_book/shell.py +241 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/__init__.py +7 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/anywidgets.py +257 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/callouts.py +106 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/link_rewrites.py +96 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/marimo_export.py +327 -0
- marimo_book-0.1.0a1/src/marimo_book/transforms/md_roles.py +78 -0
- marimo_book-0.1.0a1/src/marimo_book/watcher.py +235 -0
- marimo_book-0.1.0a1/tests/__init__.py +0 -0
- marimo_book-0.1.0a1/tests/fixtures/simple_notebook.py +43 -0
- marimo_book-0.1.0a1/tests/phase0_spike/README.md +36 -0
- marimo_book-0.1.0a1/tests/phase0_spike/RESULTS.md +51 -0
- marimo_book-0.1.0a1/tests/phase0_spike/SYNTAX_INVENTORY.md +69 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/index.md +23 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/javascripts/mathjax.js +19 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page01.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page02.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page03.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page04.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page05.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page06.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page07.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page08.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page09.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/many/page10.md +7 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/plotly.md +30 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/prose.md +66 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/stylesheets/extra.css +20 -0
- marimo_book-0.1.0a1/tests/phase0_spike/docs/widget.md +42 -0
- marimo_book-0.1.0a1/tests/phase0_spike/mkdocs.yml +90 -0
- marimo_book-0.1.0a1/tests/test_cli_commands.py +113 -0
- marimo_book-0.1.0a1/tests/test_config.py +91 -0
- marimo_book-0.1.0a1/tests/test_dependencies.py +91 -0
- marimo_book-0.1.0a1/tests/test_link_rewrites.py +85 -0
- marimo_book-0.1.0a1/tests/test_transforms.py +143 -0
- marimo_book-0.1.0a1/tests/test_watcher.py +202 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
- name: Install
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade pip
|
|
29
|
+
pip install -e '.[dev]'
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: ruff check src/ tests/
|
|
32
|
+
- name: Format check
|
|
33
|
+
run: ruff format --check src/ tests/
|
|
34
|
+
- name: Test
|
|
35
|
+
run: pytest -q
|
|
36
|
+
|
|
37
|
+
build:
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
needs: test
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- name: Set up Python
|
|
43
|
+
uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: "3.13"
|
|
46
|
+
- name: Install build backend
|
|
47
|
+
run: python -m pip install build
|
|
48
|
+
- name: Build sdist + wheel
|
|
49
|
+
run: python -m build
|
|
50
|
+
- name: Verify wheel contents
|
|
51
|
+
run: |
|
|
52
|
+
python -c "
|
|
53
|
+
import zipfile, pathlib
|
|
54
|
+
wheel = next(pathlib.Path('dist').glob('marimo_book-*.whl'))
|
|
55
|
+
with zipfile.ZipFile(wheel) as z:
|
|
56
|
+
names = z.namelist()
|
|
57
|
+
required = [
|
|
58
|
+
'marimo_book/cli.py',
|
|
59
|
+
'marimo_book/preprocessor.py',
|
|
60
|
+
'marimo_book/assets/marimo_book.js',
|
|
61
|
+
'marimo_book/assets/scaffold/book.yml',
|
|
62
|
+
'marimo_book/assets/scaffold/.gitignore',
|
|
63
|
+
'marimo_book/assets/scaffold/.github/workflows/deploy.yml',
|
|
64
|
+
]
|
|
65
|
+
missing = [f for f in required if f not in names]
|
|
66
|
+
if missing:
|
|
67
|
+
raise SystemExit(f'wheel missing files: {missing}')
|
|
68
|
+
print(f'wheel OK ({len(names)} entries)')
|
|
69
|
+
"
|
|
70
|
+
- uses: actions/upload-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist-${{ github.sha }}
|
|
73
|
+
path: dist/
|
|
74
|
+
retention-days: 7
|
|
75
|
+
|
|
76
|
+
docs:
|
|
77
|
+
# Validates that the self-hosted docs book still builds — catches
|
|
78
|
+
# regressions before they land on main. The real deploy happens in
|
|
79
|
+
# docs.yml on push to main.
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
needs: test
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- uses: actions/setup-python@v5
|
|
85
|
+
with:
|
|
86
|
+
python-version: "3.13"
|
|
87
|
+
- name: Install marimo-book with linkcheck extra
|
|
88
|
+
run: |
|
|
89
|
+
python -m pip install --upgrade pip
|
|
90
|
+
pip install -e '.[linkcheck]'
|
|
91
|
+
- name: Build docs --strict
|
|
92
|
+
run: marimo-book build -b docs/book.yml --strict
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Build and deploy docs
|
|
2
|
+
|
|
3
|
+
# Self-host marimo-book's own docs (built with marimo-book) on GitHub
|
|
4
|
+
# Pages. Triggered on pushes to main that touch the docs tree or the
|
|
5
|
+
# package source (so tool changes also re-render the docs immediately).
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
paths:
|
|
11
|
+
- "docs/**"
|
|
12
|
+
- "src/**"
|
|
13
|
+
- "pyproject.toml"
|
|
14
|
+
- ".github/workflows/docs.yml"
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
pages: write
|
|
20
|
+
id-token: write
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: docs-pages
|
|
24
|
+
cancel-in-progress: true
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.13"
|
|
34
|
+
- name: Install marimo-book (editable)
|
|
35
|
+
run: pip install -e '.[linkcheck]'
|
|
36
|
+
- name: Build docs
|
|
37
|
+
run: marimo-book build -b docs/book.yml --strict
|
|
38
|
+
- uses: actions/upload-pages-artifact@v3
|
|
39
|
+
with:
|
|
40
|
+
path: docs/_site
|
|
41
|
+
|
|
42
|
+
deploy:
|
|
43
|
+
needs: build
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
environment:
|
|
46
|
+
name: github-pages
|
|
47
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
48
|
+
steps:
|
|
49
|
+
- id: deployment
|
|
50
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes on any tag matching v*.
|
|
4
|
+
# Uses PyPI's Trusted Publisher setup (OIDC — no API token needed) — you
|
|
5
|
+
# must first register this repo + workflow on PyPI:
|
|
6
|
+
# https://docs.pypi.org/trusted-publishers/
|
|
7
|
+
#
|
|
8
|
+
# Project name on PyPI: marimo-book
|
|
9
|
+
# Owner / repo: ljchang/marimo-book
|
|
10
|
+
# Workflow name: publish.yml
|
|
11
|
+
# Environment name: pypi-publish
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags: ["v*"]
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
id-token: write # required for PyPI Trusted Publisher
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.13"
|
|
31
|
+
- name: Build sdist + wheel
|
|
32
|
+
run: |
|
|
33
|
+
python -m pip install build
|
|
34
|
+
python -m build
|
|
35
|
+
- uses: actions/upload-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
|
|
40
|
+
publish:
|
|
41
|
+
needs: build
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment:
|
|
44
|
+
name: pypi-publish
|
|
45
|
+
url: https://pypi.org/p/marimo-book
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/download-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
# No `with:` block needed — trusted publishing pulls creds from
|
|
53
|
+
# PyPI's OIDC handshake with GitHub.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.eggs/
|
|
11
|
+
wheels/
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
.env
|
|
18
|
+
|
|
19
|
+
# Testing / coverage
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.coverage
|
|
22
|
+
.coverage.*
|
|
23
|
+
htmlcov/
|
|
24
|
+
.tox/
|
|
25
|
+
.nox/
|
|
26
|
+
|
|
27
|
+
# Type checkers
|
|
28
|
+
.mypy_cache/
|
|
29
|
+
.pyre/
|
|
30
|
+
.pytype/
|
|
31
|
+
.ruff_cache/
|
|
32
|
+
|
|
33
|
+
# marimo-book build artifacts
|
|
34
|
+
_site/
|
|
35
|
+
_site_src/
|
|
36
|
+
.marimo_book_cache/
|
|
37
|
+
|
|
38
|
+
# Editors
|
|
39
|
+
.vscode/
|
|
40
|
+
.idea/
|
|
41
|
+
*.swp
|
|
42
|
+
*.swo
|
|
43
|
+
.DS_Store
|
|
44
|
+
|
|
45
|
+
# uv
|
|
46
|
+
uv.lock
|
|
47
|
+
.python-version
|
|
48
|
+
__marimo__/
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `marimo-book` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0a1] — 2026-04-24
|
|
9
|
+
|
|
10
|
+
First alpha release. Usable end-to-end for single-book sites.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
**CLI** (`marimo-book ...`)
|
|
15
|
+
|
|
16
|
+
- `new <dir>` — scaffold a new book (book.yml, content/, .gitignore,
|
|
17
|
+
.github/workflows/deploy.yml, README). `--force` to write into
|
|
18
|
+
non-empty directories.
|
|
19
|
+
- `build` — preprocess + emit static site to `_site/`. `--strict` fails
|
|
20
|
+
on warnings; `--clean` blows away prior build artifacts first.
|
|
21
|
+
- `serve` — dev server with live reload. Runs an initial build, spawns
|
|
22
|
+
`mkdocs serve`, and a watchdog observer rebuilds on changes to
|
|
23
|
+
`content/` or `book.yml`.
|
|
24
|
+
- `check` — validate `book.yml` + referenced files without building.
|
|
25
|
+
- `clean` — remove `_site/`, `_site_src/`, `.marimo_book_cache/`.
|
|
26
|
+
|
|
27
|
+
**Config** (`book.yml`)
|
|
28
|
+
|
|
29
|
+
- Pydantic v2 schema with readable errors for unknown keys.
|
|
30
|
+
- Discriminated-union TOC (`file:` / `url:` / `section:` + `children:`).
|
|
31
|
+
- Author metadata, branding (logo, favicon, palette, fonts), launch
|
|
32
|
+
buttons, bibliography paths, analytics (Plausible / Google), per-page
|
|
33
|
+
render defaults, per-widget-class default state.
|
|
34
|
+
- Top-level `shell:` reserved for future `zensical` / `jinja` targets.
|
|
35
|
+
|
|
36
|
+
**Preprocessor transforms**
|
|
37
|
+
|
|
38
|
+
- `marimo_export` — `.py` → Markdown + inline HTML via
|
|
39
|
+
`marimo export ipynb --include-outputs`. Handles hide_code, mime bundles
|
|
40
|
+
(text/html, text/markdown, image/png|jpeg|svg+xml, text/plain,
|
|
41
|
+
streams, errors), and first-setup-cell elision.
|
|
42
|
+
- `callouts` — `<marimo-callout-output>` → Material admonition with the
|
|
43
|
+
kind mapped (info/note/success/tip/warning/danger/failure/neutral).
|
|
44
|
+
- `anywidgets` — `<marimo-anywidget>` → `<div class="marimo-book-anywidget">`
|
|
45
|
+
mount; AST-walks cell source to extract literal widget kwargs; merges
|
|
46
|
+
with `book.yml` `widget_defaults`. Strips
|
|
47
|
+
`<marimo-ui-element>` / `<marimo-slider>` / etc. wrappers around
|
|
48
|
+
kernel-dependent controls that have no static analog.
|
|
49
|
+
- `md_roles` — `{download}\`label <path>\`` → `[label](path)`;
|
|
50
|
+
`:::{glossary}` fence stripping.
|
|
51
|
+
- `link_rewrites` — `.ipynb` cross-refs → `.md` (when target exists);
|
|
52
|
+
`../images/` → `images/` in both Markdown links and HTML attrs.
|
|
53
|
+
|
|
54
|
+
**Shell generator**
|
|
55
|
+
|
|
56
|
+
- `book.yml` → `mkdocs.yml` with Material theme, standard pymdownx
|
|
57
|
+
extensions (arithmatex, admonition, blocks, details, highlight,
|
|
58
|
+
superfences, tabbed, tasklist), sensible nav feature flags, and an
|
|
59
|
+
`extra.css` derived from the book's palette.
|
|
60
|
+
|
|
61
|
+
**Runtime shim** (`assets/marimo_book.js`)
|
|
62
|
+
|
|
63
|
+
- Minimal anywidget-compatible model loader. At page load, finds every
|
|
64
|
+
`.marimo-book-anywidget` mount, decodes the inlined ES module from
|
|
65
|
+
`data-js-url`, and calls `module.default.render({model, el})` with a
|
|
66
|
+
seeded model. Works with Material's instant-navigation via
|
|
67
|
+
`document$.subscribe`.
|
|
68
|
+
|
|
69
|
+
### Verified
|
|
70
|
+
|
|
71
|
+
- Full test suite: 46 passing across config, transforms, CLI, and watcher.
|
|
72
|
+
- End-to-end dartbrains build (34 TOC entries, 20 marimo notebooks):
|
|
73
|
+
0 preprocessor errors, 2 cosmetic mkdocs warnings (both broken-link
|
|
74
|
+
issues in dartbrains source content, not tool bugs).
|
|
75
|
+
- Widget-heavy chapter (MR_Physics.py, 9 anywidgets) renders and animates
|
|
76
|
+
in a browser without marimo's frontend runtime.
|
|
77
|
+
|
|
78
|
+
### Known limitations
|
|
79
|
+
|
|
80
|
+
- No WASM / hybrid render modes yet (static only).
|
|
81
|
+
- No dependency-graph-aware incremental cache; every rebuild is a full
|
|
82
|
+
rebuild.
|
|
83
|
+
- MyST cross-refs with `{ref}`, `{numref}`, `{eq}`, `{cite}`, etc. are
|
|
84
|
+
stripped through unchanged (no usage in any book we've migrated yet).
|
|
85
|
+
- Material for MkDocs is entering maintenance mode in ~12 months;
|
|
86
|
+
`marimo-book` is explicitly designed to port to [zensical](https://zensical.org)
|
|
87
|
+
when it stabilises (same `mkdocs.yml`, different build command).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luke Chang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: marimo-book
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Build clean, searchable static books from marimo notebooks and markdown
|
|
5
|
+
Project-URL: Homepage, https://github.com/ljchang/marimo-book
|
|
6
|
+
Project-URL: Repository, https://github.com/ljchang/marimo-book
|
|
7
|
+
Project-URL: Issues, https://github.com/ljchang/marimo-book/issues
|
|
8
|
+
Author-email: Luke Chang <luke.j.chang@dartmouth.edu>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: book,documentation,marimo,mkdocs,notebook,static-site
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Documentation
|
|
21
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
22
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
25
|
+
Requires-Dist: jinja2>=3.1
|
|
26
|
+
Requires-Dist: lxml>=5.0
|
|
27
|
+
Requires-Dist: marimo<0.24,>=0.23
|
|
28
|
+
Requires-Dist: mkdocs-material>=9.5
|
|
29
|
+
Requires-Dist: mkdocs>=1.6
|
|
30
|
+
Requires-Dist: nbformat>=5.0
|
|
31
|
+
Requires-Dist: pybtex>=0.24
|
|
32
|
+
Requires-Dist: pydantic>=2.6
|
|
33
|
+
Requires-Dist: pymdown-extensions>=10.7
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Requires-Dist: typer>=0.12
|
|
36
|
+
Requires-Dist: watchdog>=4.0
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
41
|
+
Provides-Extra: linkcheck
|
|
42
|
+
Requires-Dist: mkdocs-htmlproofer-plugin>=1.3; extra == 'linkcheck'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# marimo-book
|
|
46
|
+
|
|
47
|
+
Build clean, searchable static books from [marimo](https://marimo.io)
|
|
48
|
+
notebooks and Markdown files.
|
|
49
|
+
|
|
50
|
+
`marimo-book` is a Jupyter-Book-style static site generator built
|
|
51
|
+
specifically for marimo `.py` notebooks. It produces polished multi-page
|
|
52
|
+
sites with:
|
|
53
|
+
|
|
54
|
+
- **Collapsible sidebar** and chapter-aware navigation
|
|
55
|
+
- **Fast full-text search** across prose *and* baked cell outputs
|
|
56
|
+
- **Admonitions, math, figures, tables** with Material for MkDocs defaults
|
|
57
|
+
- **Anywidgets that render statically** (no marimo kernel required)
|
|
58
|
+
- **Launch buttons** per-chapter for molab / GitHub / download `.py`
|
|
59
|
+
- **Dark-mode toggle** that persists across navigation
|
|
60
|
+
- **GitHub Pages deploy workflow** scaffolded in for you
|
|
61
|
+
|
|
62
|
+
## Status
|
|
63
|
+
|
|
64
|
+
**Alpha** (v0.1.0a1, April 2026). `marimo-book` is usable end-to-end and is
|
|
65
|
+
actively building a real course site ([dartbrains](https://github.com/ljchang/dartbrains)),
|
|
66
|
+
but the `book.yml` schema may still change before v1.0. Pin the exact version
|
|
67
|
+
in your project until we signal stability.
|
|
68
|
+
|
|
69
|
+
## Install
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install marimo-book
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Requires Python 3.11+.
|
|
76
|
+
|
|
77
|
+
## Quickstart
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Scaffold a new book
|
|
81
|
+
marimo-book new mybook
|
|
82
|
+
cd mybook
|
|
83
|
+
|
|
84
|
+
# Live-reload dev server (http://127.0.0.1:8000/)
|
|
85
|
+
marimo-book serve
|
|
86
|
+
#
|
|
87
|
+
# Note on macOS: mkdocs's browser auto-reload is flaky on some
|
|
88
|
+
# macOS setups. If the browser doesn't refresh automatically after a
|
|
89
|
+
# save, hard-refresh (Cmd-R). The preprocessor + rebuild are
|
|
90
|
+
# reliable; only the browser push is affected.
|
|
91
|
+
|
|
92
|
+
# One-shot static build (emits ./_site/)
|
|
93
|
+
marimo-book build
|
|
94
|
+
|
|
95
|
+
# Validate book.yml + content without building
|
|
96
|
+
marimo-book check
|
|
97
|
+
|
|
98
|
+
# Remove build artifacts
|
|
99
|
+
marimo-book clean
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Deploy to GitHub Pages by pushing the scaffolded workflow
|
|
103
|
+
(`.github/workflows/deploy.yml`) to `main` on a repo with Pages enabled.
|
|
104
|
+
|
|
105
|
+
## How it works
|
|
106
|
+
|
|
107
|
+
Two-stage build, by design:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
content/*.md + *.py + book.yml
|
|
111
|
+
→ marimo-book preprocessor
|
|
112
|
+
→ _site_src/docs/*.md + _site_src/mkdocs.yml
|
|
113
|
+
→ mkdocs build (Material theme)
|
|
114
|
+
→ _site/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
1. The preprocessor reads `book.yml` and walks the TOC. For each `.md` it
|
|
118
|
+
applies small content transforms (MyST `:::{glossary}` fence stripping,
|
|
119
|
+
`{download}` role rewrite, `../images/` path fixups, `.ipynb` →
|
|
120
|
+
`.md` cross-ref rewriting). For each marimo `.py` it runs
|
|
121
|
+
`marimo export ipynb --include-outputs` and converts the cells into
|
|
122
|
+
Markdown + inline HTML, translating marimo custom elements
|
|
123
|
+
(`<marimo-callout-output>`, `<marimo-anywidget>`) into their static
|
|
124
|
+
analogs.
|
|
125
|
+
2. Material for MkDocs (or later, zensical — which reuses `mkdocs.yml`
|
|
126
|
+
verbatim) builds the final HTML.
|
|
127
|
+
|
|
128
|
+
The preprocessor is **not** a mkdocs plugin — it emits plain Markdown +
|
|
129
|
+
inline HTML. This keeps the shell swappable: Material today, zensical
|
|
130
|
+
tomorrow, or a hand-rolled Jinja shell as a last-resort fallback.
|
|
131
|
+
|
|
132
|
+
## `book.yml`
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
title: My Book
|
|
136
|
+
description: A static site from marimo notebooks + Markdown.
|
|
137
|
+
authors:
|
|
138
|
+
- name: Your Name
|
|
139
|
+
orcid: 0000-0000-0000-0000 # optional
|
|
140
|
+
repo: https://github.com/you/yourbook
|
|
141
|
+
branch: main
|
|
142
|
+
|
|
143
|
+
theme:
|
|
144
|
+
palette:
|
|
145
|
+
primary: "#1976D2"
|
|
146
|
+
accent: "#FF9800"
|
|
147
|
+
|
|
148
|
+
launch_buttons:
|
|
149
|
+
molab: true # "Open in molab" button on every .py page
|
|
150
|
+
github: true # "View on GitHub"
|
|
151
|
+
download: true # "Download .py source"
|
|
152
|
+
|
|
153
|
+
# Per-widget default state for anywidgets whose JS needs initial model
|
|
154
|
+
# values to render on first paint. Literal kwargs from the cell override
|
|
155
|
+
# these; unset keys fall through to the widget's own JS defaults.
|
|
156
|
+
widget_defaults:
|
|
157
|
+
CompassWidget:
|
|
158
|
+
b0: 3.0
|
|
159
|
+
|
|
160
|
+
toc:
|
|
161
|
+
- file: content/intro.md
|
|
162
|
+
- section: Part I
|
|
163
|
+
children:
|
|
164
|
+
- file: content/chapter1.py
|
|
165
|
+
- file: content/chapter2.py
|
|
166
|
+
- section: Part II
|
|
167
|
+
children:
|
|
168
|
+
- file: content/chapter3.py
|
|
169
|
+
- url: https://example.org/external-reading
|
|
170
|
+
title: External Reading
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
See `marimo-book new` for a full starter template with comments on every
|
|
174
|
+
field.
|
|
175
|
+
|
|
176
|
+
## What's supported in v0.1
|
|
177
|
+
|
|
178
|
+
**Material for MkDocs handles natively (free):**
|
|
179
|
+
|
|
180
|
+
- Full-text search, dark mode, keyboard shortcuts, code-copy buttons,
|
|
181
|
+
collapsible sidebar, breadcrumbs, next/previous navigation,
|
|
182
|
+
admonitions (`!!! note` / `!!! tip` / `!!! warning` / etc.), math,
|
|
183
|
+
responsive theme, edit-this-page link, analytics, top-of-page banner
|
|
184
|
+
|
|
185
|
+
**Preprocessor adds:**
|
|
186
|
+
|
|
187
|
+
- `book.yml` → `mkdocs.yml` generation (TOC, theme, palette, fonts,
|
|
188
|
+
extensions, plugins all derived)
|
|
189
|
+
- `.py` → rendered Markdown + inlined anywidget / callout / image outputs
|
|
190
|
+
- Static rehydration of anywidgets via a small JS shim
|
|
191
|
+
(`marimo_book.js`, loaded via `extra_javascript`)
|
|
192
|
+
- Launch-button row per chapter (molab / GitHub / download)
|
|
193
|
+
- MyST `{download}\`label <path>\`` → `[label](path)`
|
|
194
|
+
- `:::{glossary}` fence stripping (definition lists pass through natively)
|
|
195
|
+
- `[text](Foo.ipynb)` → `[text](Foo.md)` cross-ref rewrite when `Foo.md`
|
|
196
|
+
exists in the staged tree
|
|
197
|
+
- `../images/` → `images/` relative-path fixup when `content/` is flattened
|
|
198
|
+
- First-code-cell hiding (the setup-imports convention) — opt out via
|
|
199
|
+
`defaults.hide_first_code_cell: false`
|
|
200
|
+
|
|
201
|
+
## Notebook dependencies
|
|
202
|
+
|
|
203
|
+
Notebooks need their imports satisfied at build time (marimo re-executes
|
|
204
|
+
every cell to capture outputs). `marimo-book` supports two modes; pick
|
|
205
|
+
in `book.yml`:
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
dependencies:
|
|
209
|
+
mode: env # default — reuse the active venv
|
|
210
|
+
# mode: sandbox # per-notebook PEP 723 isolation via uv
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**`env` mode** (default). Whatever Python env runs `marimo-book` provides
|
|
214
|
+
the deps. The typical consumer has a `pyproject.toml` at the book root
|
|
215
|
+
listing notebook dependencies (`numpy`, `pandas`, your domain package,
|
|
216
|
+
etc.), installs with `pip install -e .` or `uv pip install -e .`, and
|
|
217
|
+
runs `marimo-book` from that env. Fast, straightforward, good when all
|
|
218
|
+
notebooks share the same stack.
|
|
219
|
+
|
|
220
|
+
**`sandbox` mode.** Passes `--sandbox` to `marimo export`. Each notebook
|
|
221
|
+
must declare its own deps via PEP 723 inline script metadata:
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
# /// script
|
|
225
|
+
# dependencies = [
|
|
226
|
+
# "marimo>=0.23",
|
|
227
|
+
# "numpy>=2.0",
|
|
228
|
+
# "pandas>=2.0",
|
|
229
|
+
# ]
|
|
230
|
+
# ///
|
|
231
|
+
|
|
232
|
+
import marimo
|
|
233
|
+
# ...
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
At build time, marimo uses `uv run --isolated` to provision a fresh env
|
|
237
|
+
per notebook. ~5–10 s on first run, cached after. Notebooks become
|
|
238
|
+
portable — copy a `.py` into any repo with `uv` installed and it just
|
|
239
|
+
works. The book root doesn't need a `pyproject.toml`.
|
|
240
|
+
|
|
241
|
+
**Override per invocation:**
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
marimo-book build --sandbox # force sandbox regardless of book.yml
|
|
245
|
+
marimo-book build --no-sandbox # force env mode
|
|
246
|
+
marimo-book serve --sandbox # slower iteration, but reproducible
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Use `env` for local dev loops and `sandbox` on CI where reproducibility
|
|
250
|
+
matters more than rebuild speed.
|
|
251
|
+
|
|
252
|
+
## Broken-link checking
|
|
253
|
+
|
|
254
|
+
`mkdocs build --strict` (use `marimo-book build --strict`) already fails on
|
|
255
|
+
broken **in-tree** links and anchors. For external URLs and image `src`
|
|
256
|
+
attributes, opt into the `htmlproofer` plugin:
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
# book.yml
|
|
260
|
+
check_external_links: true
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
pip install 'marimo-book[linkcheck]'
|
|
265
|
+
marimo-book build --strict
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
External link checking hits the live web, so it's slow (~1–3 s per link).
|
|
269
|
+
Keep it off on CI unless you're cutting a release.
|
|
270
|
+
|
|
271
|
+
**Not in v0.1 (planned):**
|
|
272
|
+
|
|
273
|
+
- WASM / hybrid render modes — static only in v0.1; architecture already
|
|
274
|
+
supports the branch
|
|
275
|
+
- Dependency-graph-aware incremental build cache
|
|
276
|
+
- BibTeX citations with hover-cards (no book needs them yet)
|
|
277
|
+
- PDF / EPUB export — opt-in via `mkdocs-with-pdf` if needed
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
[MIT](LICENSE)
|