manim-simplex 0.2.0__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.
- manim_simplex-0.2.0/.gitignore +30 -0
- manim_simplex-0.2.0/.pre-commit-config.yaml +66 -0
- manim_simplex-0.2.0/.python-version +1 -0
- manim_simplex-0.2.0/CHANGELOG.md +114 -0
- manim_simplex-0.2.0/LICENSE +21 -0
- manim_simplex-0.2.0/PKG-INFO +214 -0
- manim_simplex-0.2.0/README.md +182 -0
- manim_simplex-0.2.0/examples/README.md +33 -0
- manim_simplex-0.2.0/examples/glyph_map_demo.py +27 -0
- manim_simplex-0.2.0/examples/hello_slide.py +36 -0
- manim_simplex-0.2.0/examples/manim.cfg +3 -0
- manim_simplex-0.2.0/examples/outline_slide.py +28 -0
- manim_simplex-0.2.0/examples/theme_demo.py +25 -0
- manim_simplex-0.2.0/pyproject.toml +102 -0
- manim_simplex-0.2.0/ruff.toml +43 -0
- manim_simplex-0.2.0/src/simplex/engine/README.md +38 -0
- manim_simplex-0.2.0/src/simplex/engine/__init__.py +31 -0
- manim_simplex-0.2.0/src/simplex/engine/animations.py +160 -0
- manim_simplex-0.2.0/src/simplex/engine/code.py +442 -0
- manim_simplex-0.2.0/src/simplex/engine/debug.py +181 -0
- manim_simplex-0.2.0/src/simplex/engine/defaults.py +33 -0
- manim_simplex-0.2.0/src/simplex/engine/dynamics.py +100 -0
- manim_simplex-0.2.0/src/simplex/engine/geometry.py +247 -0
- manim_simplex-0.2.0/src/simplex/engine/ghost_fade.py +72 -0
- manim_simplex-0.2.0/src/simplex/engine/glyph_map.py +339 -0
- manim_simplex-0.2.0/src/simplex/engine/region.py +304 -0
- manim_simplex-0.2.0/src/simplex/engine/scaling.py +77 -0
- manim_simplex-0.2.0/src/simplex/engine/text.py +110 -0
- manim_simplex-0.2.0/src/simplex/manifest.py +114 -0
- manim_simplex-0.2.0/src/simplex/mobjects/README.md +33 -0
- manim_simplex-0.2.0/src/simplex/mobjects/__init__.py +13 -0
- manim_simplex-0.2.0/src/simplex/mobjects/array.py +408 -0
- manim_simplex-0.2.0/src/simplex/mobjects/graph.py +59 -0
- manim_simplex-0.2.0/src/simplex/mobjects/outline.py +141 -0
- manim_simplex-0.2.0/src/simplex/plugin.py +74 -0
- manim_simplex-0.2.0/src/simplex/py.typed +0 -0
- manim_simplex-0.2.0/src/simplex/section.py +51 -0
- manim_simplex-0.2.0/src/simplex/slides/README.md +43 -0
- manim_simplex-0.2.0/src/simplex/slides/__init__.py +12 -0
- manim_simplex-0.2.0/src/simplex/slides/base.py +118 -0
- manim_simplex-0.2.0/src/simplex/slides/chrome.py +69 -0
- manim_simplex-0.2.0/src/simplex/slides/outline.py +433 -0
- manim_simplex-0.2.0/src/simplex/theme/README.md +19 -0
- manim_simplex-0.2.0/src/simplex/theme/__init__.py +28 -0
- manim_simplex-0.2.0/src/simplex/theme/context.py +29 -0
- manim_simplex-0.2.0/src/simplex/theme/presets.py +87 -0
- manim_simplex-0.2.0/src/simplex/theme/pygments_style.py +78 -0
- manim_simplex-0.2.0/src/simplex/theme/tokens.py +105 -0
- manim_simplex-0.2.0/src/simplex/theme/web_css.py +33 -0
- manim_simplex-0.2.0/tests/README.md +27 -0
- manim_simplex-0.2.0/tests/__init__.py +0 -0
- manim_simplex-0.2.0/tests/engine/README.md +22 -0
- manim_simplex-0.2.0/tests/engine/__init__.py +0 -0
- manim_simplex-0.2.0/tests/engine/test_animations.py +56 -0
- manim_simplex-0.2.0/tests/engine/test_code.py +145 -0
- manim_simplex-0.2.0/tests/engine/test_debug.py +42 -0
- manim_simplex-0.2.0/tests/engine/test_dynamics.py +33 -0
- manim_simplex-0.2.0/tests/engine/test_geometry.py +83 -0
- manim_simplex-0.2.0/tests/engine/test_ghost_fade.py +21 -0
- manim_simplex-0.2.0/tests/engine/test_glyph_map.py +24 -0
- manim_simplex-0.2.0/tests/engine/test_region.py +222 -0
- manim_simplex-0.2.0/tests/engine/test_scaling.py +38 -0
- manim_simplex-0.2.0/tests/engine/test_text.py +67 -0
- manim_simplex-0.2.0/tests/mobjects/README.md +16 -0
- manim_simplex-0.2.0/tests/mobjects/__init__.py +0 -0
- manim_simplex-0.2.0/tests/mobjects/test_graph.py +35 -0
- manim_simplex-0.2.0/tests/mobjects/test_outline.py +64 -0
- manim_simplex-0.2.0/tests/slides/README.md +20 -0
- manim_simplex-0.2.0/tests/slides/__init__.py +0 -0
- manim_simplex-0.2.0/tests/slides/test_base.py +96 -0
- manim_simplex-0.2.0/tests/slides/test_chrome.py +55 -0
- manim_simplex-0.2.0/tests/slides/test_outline.py +141 -0
- manim_simplex-0.2.0/tests/test_manifest.py +134 -0
- manim_simplex-0.2.0/tests/test_section.py +75 -0
- manim_simplex-0.2.0/tests/theme/README.md +8 -0
- manim_simplex-0.2.0/tests/theme/__init__.py +0 -0
- manim_simplex-0.2.0/tests/theme/test_tokens.py +52 -0
- manim_simplex-0.2.0/tests/theme/test_web_css.py +18 -0
- manim_simplex-0.2.0/uv.lock +1422 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.so
|
|
5
|
+
|
|
6
|
+
# Build artifacts
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# uv
|
|
13
|
+
.venv/
|
|
14
|
+
|
|
15
|
+
# Tool caches
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.basedpyright/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
|
|
21
|
+
# Manim output
|
|
22
|
+
media/
|
|
23
|
+
# manim-slides output (rooted, so tests/slides/ stays tracked)
|
|
24
|
+
/slides/
|
|
25
|
+
|
|
26
|
+
# Editors
|
|
27
|
+
.idea/
|
|
28
|
+
.vscode/
|
|
29
|
+
*.swp
|
|
30
|
+
.DS_Store
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
ci:
|
|
2
|
+
autofix_commit_msg: |
|
|
3
|
+
chore(fmt): auto fixes from pre-commit.com hooks
|
|
4
|
+
|
|
5
|
+
for more information, see https://pre-commit.ci
|
|
6
|
+
autoupdate_commit_msg: 'chore(deps): pre-commit autoupdate'
|
|
7
|
+
|
|
8
|
+
default_stages:
|
|
9
|
+
- pre-commit
|
|
10
|
+
- pre-push
|
|
11
|
+
|
|
12
|
+
repos:
|
|
13
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
14
|
+
rev: v6.0.0
|
|
15
|
+
hooks:
|
|
16
|
+
- id: check-yaml
|
|
17
|
+
- id: check-toml
|
|
18
|
+
- id: end-of-file-fixer
|
|
19
|
+
- id: trailing-whitespace
|
|
20
|
+
- id: check-merge-conflict
|
|
21
|
+
- id: check-added-large-files
|
|
22
|
+
args: [--maxkb=512]
|
|
23
|
+
- id: mixed-line-ending
|
|
24
|
+
args: [--fix=lf]
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
|
27
|
+
rev: v2.16.0
|
|
28
|
+
hooks:
|
|
29
|
+
- id: pretty-format-yaml
|
|
30
|
+
args: [--autofix]
|
|
31
|
+
- id: pretty-format-toml
|
|
32
|
+
exclude: ^(uv\.lock|poetry\.lock)$
|
|
33
|
+
args: [--autofix, --trailing-commas]
|
|
34
|
+
|
|
35
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
36
|
+
rev: v0.15.12
|
|
37
|
+
hooks:
|
|
38
|
+
- id: ruff
|
|
39
|
+
args: [--fix]
|
|
40
|
+
- id: ruff-format
|
|
41
|
+
|
|
42
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
43
|
+
rev: v1.20.2
|
|
44
|
+
hooks:
|
|
45
|
+
- id: mypy
|
|
46
|
+
additional_dependencies: [types-requests, types-setuptools]
|
|
47
|
+
args: [--ignore-missing-imports]
|
|
48
|
+
files: ^src/
|
|
49
|
+
|
|
50
|
+
- repo: https://github.com/codespell-project/codespell
|
|
51
|
+
rev: v2.4.2
|
|
52
|
+
hooks:
|
|
53
|
+
- id: codespell
|
|
54
|
+
additional_dependencies:
|
|
55
|
+
- tomli
|
|
56
|
+
args: [--ignore-words-list=manim, mobjects, mobject]
|
|
57
|
+
exclude: ^(uv\.lock|.*\.svg)$
|
|
58
|
+
|
|
59
|
+
- repo: local
|
|
60
|
+
hooks:
|
|
61
|
+
- id: github-issues
|
|
62
|
+
name: GitHub issues link check
|
|
63
|
+
description: Check issues (and PR) links are matching number.
|
|
64
|
+
entry: python .github/scripts/check_github_issues.py
|
|
65
|
+
language: system
|
|
66
|
+
types: [markdown]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `manim-simplex` are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
5
|
+
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.0] - 2026-05-24
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `TexPage` mobject — fixed-width minipage helper. Width is configurable
|
|
14
|
+
via the ``width_cm`` kwarg (default 20.0) or by overriding the class
|
|
15
|
+
attribute on a subclass. Replaces the old ``Definition`` mobject; the
|
|
16
|
+
hardcoded minipage literal no longer appears in presets or
|
|
17
|
+
tests.
|
|
18
|
+
- `Region.split(axis, k)` — divide a region into ``k`` sub-regions
|
|
19
|
+
along a cardinal direction. Each piece keeps the perpendicular extent
|
|
20
|
+
and gets ``1/k`` of the axis extent; pieces are returned in the
|
|
21
|
+
direction of ``axis``. Their union equals the original region.
|
|
22
|
+
- `Spacing.header_buff` / `Spacing.footer_buff` — chrome gap distances
|
|
23
|
+
exposed on the theme so they can be tuned deck-wide without editing
|
|
24
|
+
``make_chrome``.
|
|
25
|
+
- `simplex.manifest` module — Pydantic models (`DeckManifest`, `MainSlide`,
|
|
26
|
+
`Subsection`) that define the cross-package contract between the plugin
|
|
27
|
+
and the `simplex` web builder. The web builder now imports the schema
|
|
28
|
+
from the plugin rather than redefining it locally.
|
|
29
|
+
- `simplex.section` module — `SimplexSectionType` enum promoted to the
|
|
30
|
+
package root (previously `simplex.engine.section_types`). Manim-free so
|
|
31
|
+
the web builder and CLI can use it without paying for a Manim import.
|
|
32
|
+
- `simplex.mobjects` subpackage — `Node`, `Edge`, `ArrayMob`, `ArrayEntry`,
|
|
33
|
+
`ArrayPointer` promoted from `simplex.slides.components` to a top-level
|
|
34
|
+
mobjects package, matching Manim's own `manim.mobject.*` convention.
|
|
35
|
+
- `simplex.slides.Chrome` NamedTuple — pure factory return type combining
|
|
36
|
+
the canvas mobjects dict and the body region.
|
|
37
|
+
- `simplex.engine.HighlightResult` dataclass — typed return for
|
|
38
|
+
`highlight_code_lines`, iterable so the existing `self.play(*result)`
|
|
39
|
+
pattern still works.
|
|
40
|
+
- `py.typed` marker — downstream `pyright`/`mypy` users now get type
|
|
41
|
+
information for the `simplex` namespace.
|
|
42
|
+
- `examples/` directory — runnable demo scenes (`hello_slide.py`,
|
|
43
|
+
`theme_demo.py`, `glyph_map_demo.py`) used as documentation and CI
|
|
44
|
+
fixtures.
|
|
45
|
+
- `.pre-commit-config.yaml` — ruff, ruff-format, codespell, and standard
|
|
46
|
+
whitespace/yaml/toml hygiene hooks.
|
|
47
|
+
- CHANGELOG.md.
|
|
48
|
+
- CI: `manim plugins -l` discovery smoke test alongside the existing
|
|
49
|
+
import smoke.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- **BREAKING:** ``Region.place`` now takes a Manim **direction vector**
|
|
54
|
+
(``UP``, ``DR``, ``ORIGIN``, …) instead of a string anchor name. The
|
|
55
|
+
same applies to the ``_anchor_point`` helper. Migrate
|
|
56
|
+
``region.place(mob, "top", buff=…)`` → ``region.place(mob, UP, buff=…)``.
|
|
57
|
+
- **BREAKING:** ``make_chrome`` no longer accepts a ``page=`` parameter.
|
|
58
|
+
Slide numbering is presentation chrome and is now driven by the
|
|
59
|
+
RevealJS template (toggle via ``[web]`` overrides in ``deck.toml``)
|
|
60
|
+
so it survives without being baked into each frame.
|
|
61
|
+
- **BREAKING:** ``BodyText`` is removed. Plain ``manim.Tex`` carries the
|
|
62
|
+
theme's body font size through ``apply_theme_defaults`` — call sites
|
|
63
|
+
rewrite ``BodyText(...)`` to ``Tex(...)``.
|
|
64
|
+
- **BREAKING:** ``Definition`` is renamed to ``TexPage`` (and no longer
|
|
65
|
+
reads ``theme.latex.environments["definition"]``).
|
|
66
|
+
- ``BaseSlide`` auto-promotion now pretty-prints the class name into a
|
|
67
|
+
space-separated label (``DFSLecture`` → ``"DFS Lecture"``,
|
|
68
|
+
``ImplementBFSSlide`` → ``"Implement BFS Slide"``). The class name
|
|
69
|
+
itself is unchanged.
|
|
70
|
+
- **BREAKING:** Python floor raised to **3.13** (was a transitional 3.14
|
|
71
|
+
in the Phase 3 split commit). 3.13 is a long-term-supportable floor
|
|
72
|
+
with much wider availability for lecture authors.
|
|
73
|
+
- **BREAKING:** `simplex.engine.section_types` → `simplex.section`.
|
|
74
|
+
- **BREAKING:** `simplex.slides.components.{graph, array}` →
|
|
75
|
+
`simplex.mobjects.{graph, array}`.
|
|
76
|
+
- **BREAKING:** `simplex.engine.transforms` is split into
|
|
77
|
+
`simplex.engine.glyph_map` (`TransformByGlyphMap`) and
|
|
78
|
+
`simplex.engine.ghost_fade` (`GhostSlideFade`). The combined module is
|
|
79
|
+
removed.
|
|
80
|
+
- `BaseSlide.next_slide()` still auto-promotes the first bare call to
|
|
81
|
+
a main slide (named after the scene class), but no longer emits a
|
|
82
|
+
`UserWarning`. Passing `name=` on the first call still works and only
|
|
83
|
+
changes the slide's name; the section type is `MAIN` either way.
|
|
84
|
+
- **BREAKING:** `make_chrome` no longer mutates its `Region` argument.
|
|
85
|
+
It returns a `Chrome(mobjects, body_region)` NamedTuple. Callers do
|
|
86
|
+
`chrome = make_chrome(...); self.add_to_canvas(**chrome.mobjects);
|
|
87
|
+
self.region = chrome.body_region` (or destructure).
|
|
88
|
+
- **BREAKING:** `highlight_code_lines` returns `HighlightResult` (a
|
|
89
|
+
frozen dataclass with `.fade` and `.indicate`) instead of the prior
|
|
90
|
+
tuple-or-AnimationGroup union. `*result` unpacks back into the
|
|
91
|
+
previous tuple form for callers that prefer it.
|
|
92
|
+
- Exit animation overrides are now stored in a `WeakKeyDictionary`
|
|
93
|
+
registry rather than monkey-patched onto the `Mobject` as a
|
|
94
|
+
`_simplex_exit` attribute. The public API (`set_exit_animation`,
|
|
95
|
+
`exit_for`, `Remove`) is unchanged.
|
|
96
|
+
- The exit-defaults registry is now wrapped in a singleton with
|
|
97
|
+
threading.Lock-guarded lazy init, removing the module-level mutable
|
|
98
|
+
global.
|
|
99
|
+
|
|
100
|
+
### Removed
|
|
101
|
+
|
|
102
|
+
- ``BodyText`` mobject. Use ``manim.Tex`` (body size + color come from
|
|
103
|
+
``apply_theme_defaults``) or ``Caption`` for smaller annotations.
|
|
104
|
+
- ``Definition`` mobject. Replaced by ``TexPage`` (see Added/Changed).
|
|
105
|
+
- ``make_chrome(..., page=…)`` parameter and the corresponding ``page``
|
|
106
|
+
entry in ``Chrome.mobjects``. Slide numbering moves to the web layer.
|
|
107
|
+
- ``LatexProfile.environments["definition"]`` entries from
|
|
108
|
+
``DASTIMATOR_DARK`` and ``ACADEMIC_LIGHT``: ``TexPage`` is now the
|
|
109
|
+
single owner of the ``{minipage}{<width>cm}`` literal.
|
|
110
|
+
- `simplex.engine.section_types` module (replaced by `simplex.section`).
|
|
111
|
+
- `simplex.slides.components` subpackage (replaced by `simplex.mobjects`).
|
|
112
|
+
- `simplex.engine.transforms` module (split — see Changed).
|
|
113
|
+
- `UserWarning` on the first bare `BaseSlide.next_slide()` call. Auto-
|
|
114
|
+
promotion stays (named after the class), just silently.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shlomi Perles
|
|
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,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: manim-simplex
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Manim plugin: theme tokens, mobjects, slide hierarchy, deck manifest schema.
|
|
5
|
+
Project-URL: Changelog, https://github.com/shlomi-perles/manim-simplex/blob/main/CHANGELOG.md
|
|
6
|
+
Project-URL: Homepage, https://github.com/shlomi-perles/manim-simplex
|
|
7
|
+
Project-URL: Issues, https://github.com/shlomi-perles/manim-simplex/issues
|
|
8
|
+
Project-URL: Repository, https://github.com/shlomi-perles/manim-simplex
|
|
9
|
+
Author: Shlomi Perles
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: animation,computer-science,education,lecture,manim,manim-slides,math,presentation
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Education
|
|
22
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
23
|
+
Classifier: Topic :: Multimedia :: Video
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.13
|
|
27
|
+
Requires-Dist: manim-slides>=5.1.7
|
|
28
|
+
Requires-Dist: manim>=0.20.1
|
|
29
|
+
Requires-Dist: pydantic>=2.7
|
|
30
|
+
Requires-Dist: pygments>=2.18
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# manim-simplex
|
|
34
|
+
|
|
35
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
36
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
37
|
+
[](https://github.com/shlomi-perles/manim-simplex/blob/main/LICENSE)
|
|
38
|
+
|
|
39
|
+
The Manim plugin half of [Simplex](https://github.com/shlomi-perles/simplex):
|
|
40
|
+
theme tokens, reusable mobjects, slide hierarchy, deck manifest schema,
|
|
41
|
+
and the `manim.plugins` entry-point. Distributed on PyPI as
|
|
42
|
+
`manim-simplex`.
|
|
43
|
+
|
|
44
|
+
The lecture-portal platform (CLI, deck discovery, render orchestration,
|
|
45
|
+
web builder) lives in the sibling [`simplex`](https://github.com/shlomi-perles/simplex)
|
|
46
|
+
package; both contribute modules to the shared PEP 420 `simplex/`
|
|
47
|
+
namespace.
|
|
48
|
+
|
|
49
|
+
## What ships here
|
|
50
|
+
|
|
51
|
+
| Module | Contents |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `simplex.plugin` | `activate()` -- the `manim.plugins` entry-point. Applies the active theme to `manim.config`. |
|
|
54
|
+
| `simplex.section` | `SimplexSectionType` enum -- the slide-hierarchy strings written into Manim's sections JSON. Manim-free. |
|
|
55
|
+
| `simplex.manifest` | `DeckManifest`, `MainSlide`, `Subsection` Pydantic models -- the cross-package contract consumed by the `simplex` web builder. Manim-free. |
|
|
56
|
+
| `simplex.theme` | `Theme`, `Palette`, `Typography`, `Spacing`, `Motion`, `LatexProfile`, `WebPalette`, `active_theme`, `get_active_theme`, `presets`, `render_web_css`. |
|
|
57
|
+
| `simplex.engine` | Animation primitives -- `Region`, `Remove`, `clear_scene`, `exit_for`, `register_exit`, `set_exit_animation`, `HighlightResult`, `apply_theme_defaults`, plus the `glyph_map`, `ghost_fade`, `dynamics`, `geometry`, `code`, `text`, `scaling`, `debug` submodules. |
|
|
58
|
+
| `simplex.mobjects` | `Node`, `Edge`, `ArrayMob`, `ArrayEntry`, `ArrayPointer`, `OutlineProgressBar`. |
|
|
59
|
+
| `simplex.slides` | `BaseSlide`, `OutlineScene`, `OutlinePart`, `Chrome`, `make_chrome`. |
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv add manim-simplex
|
|
65
|
+
# or
|
|
66
|
+
pip install manim-simplex
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
System dependencies (texlive, ffmpeg, cairo, pango) are the same as
|
|
70
|
+
Manim's -- see the [Manim install guide](https://docs.manim.community/en/stable/installation.html).
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
```ini
|
|
75
|
+
# decks/<your-deck>/manim.cfg
|
|
76
|
+
[CLI]
|
|
77
|
+
plugins = simplex
|
|
78
|
+
save_sections = True
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from manim import MathTex
|
|
83
|
+
from simplex.slides import BaseSlide, make_chrome
|
|
84
|
+
from simplex.theme import presets
|
|
85
|
+
|
|
86
|
+
class Hello(BaseSlide):
|
|
87
|
+
def setup(self) -> None:
|
|
88
|
+
super().setup()
|
|
89
|
+
chrome = make_chrome(presets.DASTIMATOR_DARK, self.region, header="Hello")
|
|
90
|
+
self.add_to_canvas(**chrome.mobjects)
|
|
91
|
+
self.region = chrome.body_region
|
|
92
|
+
|
|
93
|
+
def construct(self) -> None:
|
|
94
|
+
from manim import ORIGIN, Write
|
|
95
|
+
eq = MathTex(r"e^{i\pi} + 1 = 0")
|
|
96
|
+
self.region.place(eq, ORIGIN)
|
|
97
|
+
self.play(Write(eq))
|
|
98
|
+
self.next_slide(name="Hello")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
uv run manim-slides render path/to/your_deck/scene.py Hello
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Slide hierarchy
|
|
106
|
+
|
|
107
|
+
`BaseSlide.next_slide` writes a `SimplexSectionType` value into Manim's
|
|
108
|
+
native section JSON. The web builder reconciles that with manim-slides'
|
|
109
|
+
`PresentationConfig` to build a main/sub tree.
|
|
110
|
+
|
|
111
|
+
- `self.next_slide(name="Title")` -> **MAIN** slide named `"Title"`.
|
|
112
|
+
- `self.next_slide()` as the *first* call -> **MAIN** slide
|
|
113
|
+
auto-named after the scene class with PascalCase boundaries spaced
|
|
114
|
+
out (``DFSLecture`` → ``"DFS Lecture"``; no warning).
|
|
115
|
+
- `self.next_slide()` after a named main -> **SUB** slide.
|
|
116
|
+
- `self.next_slide(..., loop=True)` -> the `LOOP` variant.
|
|
117
|
+
- `self.next_slide(..., section_type="simplex.main.skip")` -> explicit
|
|
118
|
+
override always wins.
|
|
119
|
+
|
|
120
|
+
## Outline slides
|
|
121
|
+
|
|
122
|
+
`OutlineScene` composes typed `OutlinePart` objects into an animated
|
|
123
|
+
`BaseSlide` outline. Each part owns already-built Manim mobjects for its
|
|
124
|
+
feature title, compact label, and optional visual. Progress dots are
|
|
125
|
+
positioned with `self.region.linspace(RIGHT, n)` defaults, so edge
|
|
126
|
+
margins and inter-dot gaps are equal.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from manim import Circle, Square, Tex
|
|
130
|
+
from simplex.engine.text import Caption
|
|
131
|
+
from simplex.slides import OutlinePart, OutlineScene
|
|
132
|
+
|
|
133
|
+
class Outline(OutlineScene):
|
|
134
|
+
def __init__(self, **kwargs):
|
|
135
|
+
super().__init__(
|
|
136
|
+
parts=[
|
|
137
|
+
OutlinePart(Tex("Research Question"), Caption("Question"), Circle()),
|
|
138
|
+
OutlinePart(Tex("Algorithms"), Caption("Algorithms"), Square()),
|
|
139
|
+
],
|
|
140
|
+
**kwargs,
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Theme
|
|
145
|
+
|
|
146
|
+
Themes are frozen Pydantic models -- the same instance produces:
|
|
147
|
+
|
|
148
|
+
1. Manim defaults (via `apply_theme_defaults`, called by the plugin).
|
|
149
|
+
2. A `TexTemplate` (via `LatexProfile.as_tex_template`).
|
|
150
|
+
3. CSS variables for the web portal + RevealJS HTML (via
|
|
151
|
+
`render_web_css(theme.web_palette)`).
|
|
152
|
+
4. The `darcula` Pygments style (registered by the plugin).
|
|
153
|
+
|
|
154
|
+
Switch themes per-scope with `active_theme`:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from simplex.theme import presets
|
|
158
|
+
from simplex.theme.context import active_theme
|
|
159
|
+
|
|
160
|
+
from manim import Tex
|
|
161
|
+
|
|
162
|
+
with active_theme(presets.ACADEMIC_LIGHT):
|
|
163
|
+
label = Tex("This Tex picks up the academic light palette.")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Cross-package contract
|
|
167
|
+
|
|
168
|
+
`manim-simplex` owns the manifest schema; `simplex` imports it:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from simplex.manifest import DeckManifest, MainSlide, Subsection
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
When the schema bumps `schema_version`, the web builder hard-fails on
|
|
175
|
+
unknown versions with a pointer at the `manim-simplex` upgrade. This
|
|
176
|
+
keeps the two repos honest about their contract.
|
|
177
|
+
|
|
178
|
+
## Why a separate distribution?
|
|
179
|
+
|
|
180
|
+
The plugin surface (mobjects + theme + entry-point + manifest schema)
|
|
181
|
+
is reusable independently of the lecture-portal pipeline. Splitting
|
|
182
|
+
them lets the plugin be a thin dependency for users who want to render
|
|
183
|
+
slides without pulling in Typer, watchfiles, Jinja, and the web
|
|
184
|
+
builder stack.
|
|
185
|
+
|
|
186
|
+
Python's PEP 420 implicit namespace packages merge the two distributions
|
|
187
|
+
at import time. Neither wheel ships `src/simplex/__init__.py`, so
|
|
188
|
+
`from simplex.engine import Remove` resolves regardless of which wheel
|
|
189
|
+
contributed the module.
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
git clone https://github.com/shlomi-perles/manim-simplex.git
|
|
197
|
+
cd manim-simplex
|
|
198
|
+
uv sync --all-extras
|
|
199
|
+
uv run pre-commit install
|
|
200
|
+
uv run pytest -q
|
|
201
|
+
uv run ruff check .
|
|
202
|
+
uv run basedpyright
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Examples under `examples/` are runnable demo scenes; they double as
|
|
206
|
+
documentation and CI smoke tests:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
uv run manim -pql examples/hello_slide.py HelloSlide
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# manim-simplex
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
4
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
5
|
+
[](https://github.com/shlomi-perles/manim-simplex/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
The Manim plugin half of [Simplex](https://github.com/shlomi-perles/simplex):
|
|
8
|
+
theme tokens, reusable mobjects, slide hierarchy, deck manifest schema,
|
|
9
|
+
and the `manim.plugins` entry-point. Distributed on PyPI as
|
|
10
|
+
`manim-simplex`.
|
|
11
|
+
|
|
12
|
+
The lecture-portal platform (CLI, deck discovery, render orchestration,
|
|
13
|
+
web builder) lives in the sibling [`simplex`](https://github.com/shlomi-perles/simplex)
|
|
14
|
+
package; both contribute modules to the shared PEP 420 `simplex/`
|
|
15
|
+
namespace.
|
|
16
|
+
|
|
17
|
+
## What ships here
|
|
18
|
+
|
|
19
|
+
| Module | Contents |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `simplex.plugin` | `activate()` -- the `manim.plugins` entry-point. Applies the active theme to `manim.config`. |
|
|
22
|
+
| `simplex.section` | `SimplexSectionType` enum -- the slide-hierarchy strings written into Manim's sections JSON. Manim-free. |
|
|
23
|
+
| `simplex.manifest` | `DeckManifest`, `MainSlide`, `Subsection` Pydantic models -- the cross-package contract consumed by the `simplex` web builder. Manim-free. |
|
|
24
|
+
| `simplex.theme` | `Theme`, `Palette`, `Typography`, `Spacing`, `Motion`, `LatexProfile`, `WebPalette`, `active_theme`, `get_active_theme`, `presets`, `render_web_css`. |
|
|
25
|
+
| `simplex.engine` | Animation primitives -- `Region`, `Remove`, `clear_scene`, `exit_for`, `register_exit`, `set_exit_animation`, `HighlightResult`, `apply_theme_defaults`, plus the `glyph_map`, `ghost_fade`, `dynamics`, `geometry`, `code`, `text`, `scaling`, `debug` submodules. |
|
|
26
|
+
| `simplex.mobjects` | `Node`, `Edge`, `ArrayMob`, `ArrayEntry`, `ArrayPointer`, `OutlineProgressBar`. |
|
|
27
|
+
| `simplex.slides` | `BaseSlide`, `OutlineScene`, `OutlinePart`, `Chrome`, `make_chrome`. |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv add manim-simplex
|
|
33
|
+
# or
|
|
34
|
+
pip install manim-simplex
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
System dependencies (texlive, ffmpeg, cairo, pango) are the same as
|
|
38
|
+
Manim's -- see the [Manim install guide](https://docs.manim.community/en/stable/installation.html).
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```ini
|
|
43
|
+
# decks/<your-deck>/manim.cfg
|
|
44
|
+
[CLI]
|
|
45
|
+
plugins = simplex
|
|
46
|
+
save_sections = True
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from manim import MathTex
|
|
51
|
+
from simplex.slides import BaseSlide, make_chrome
|
|
52
|
+
from simplex.theme import presets
|
|
53
|
+
|
|
54
|
+
class Hello(BaseSlide):
|
|
55
|
+
def setup(self) -> None:
|
|
56
|
+
super().setup()
|
|
57
|
+
chrome = make_chrome(presets.DASTIMATOR_DARK, self.region, header="Hello")
|
|
58
|
+
self.add_to_canvas(**chrome.mobjects)
|
|
59
|
+
self.region = chrome.body_region
|
|
60
|
+
|
|
61
|
+
def construct(self) -> None:
|
|
62
|
+
from manim import ORIGIN, Write
|
|
63
|
+
eq = MathTex(r"e^{i\pi} + 1 = 0")
|
|
64
|
+
self.region.place(eq, ORIGIN)
|
|
65
|
+
self.play(Write(eq))
|
|
66
|
+
self.next_slide(name="Hello")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv run manim-slides render path/to/your_deck/scene.py Hello
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Slide hierarchy
|
|
74
|
+
|
|
75
|
+
`BaseSlide.next_slide` writes a `SimplexSectionType` value into Manim's
|
|
76
|
+
native section JSON. The web builder reconciles that with manim-slides'
|
|
77
|
+
`PresentationConfig` to build a main/sub tree.
|
|
78
|
+
|
|
79
|
+
- `self.next_slide(name="Title")` -> **MAIN** slide named `"Title"`.
|
|
80
|
+
- `self.next_slide()` as the *first* call -> **MAIN** slide
|
|
81
|
+
auto-named after the scene class with PascalCase boundaries spaced
|
|
82
|
+
out (``DFSLecture`` → ``"DFS Lecture"``; no warning).
|
|
83
|
+
- `self.next_slide()` after a named main -> **SUB** slide.
|
|
84
|
+
- `self.next_slide(..., loop=True)` -> the `LOOP` variant.
|
|
85
|
+
- `self.next_slide(..., section_type="simplex.main.skip")` -> explicit
|
|
86
|
+
override always wins.
|
|
87
|
+
|
|
88
|
+
## Outline slides
|
|
89
|
+
|
|
90
|
+
`OutlineScene` composes typed `OutlinePart` objects into an animated
|
|
91
|
+
`BaseSlide` outline. Each part owns already-built Manim mobjects for its
|
|
92
|
+
feature title, compact label, and optional visual. Progress dots are
|
|
93
|
+
positioned with `self.region.linspace(RIGHT, n)` defaults, so edge
|
|
94
|
+
margins and inter-dot gaps are equal.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from manim import Circle, Square, Tex
|
|
98
|
+
from simplex.engine.text import Caption
|
|
99
|
+
from simplex.slides import OutlinePart, OutlineScene
|
|
100
|
+
|
|
101
|
+
class Outline(OutlineScene):
|
|
102
|
+
def __init__(self, **kwargs):
|
|
103
|
+
super().__init__(
|
|
104
|
+
parts=[
|
|
105
|
+
OutlinePart(Tex("Research Question"), Caption("Question"), Circle()),
|
|
106
|
+
OutlinePart(Tex("Algorithms"), Caption("Algorithms"), Square()),
|
|
107
|
+
],
|
|
108
|
+
**kwargs,
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Theme
|
|
113
|
+
|
|
114
|
+
Themes are frozen Pydantic models -- the same instance produces:
|
|
115
|
+
|
|
116
|
+
1. Manim defaults (via `apply_theme_defaults`, called by the plugin).
|
|
117
|
+
2. A `TexTemplate` (via `LatexProfile.as_tex_template`).
|
|
118
|
+
3. CSS variables for the web portal + RevealJS HTML (via
|
|
119
|
+
`render_web_css(theme.web_palette)`).
|
|
120
|
+
4. The `darcula` Pygments style (registered by the plugin).
|
|
121
|
+
|
|
122
|
+
Switch themes per-scope with `active_theme`:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from simplex.theme import presets
|
|
126
|
+
from simplex.theme.context import active_theme
|
|
127
|
+
|
|
128
|
+
from manim import Tex
|
|
129
|
+
|
|
130
|
+
with active_theme(presets.ACADEMIC_LIGHT):
|
|
131
|
+
label = Tex("This Tex picks up the academic light palette.")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Cross-package contract
|
|
135
|
+
|
|
136
|
+
`manim-simplex` owns the manifest schema; `simplex` imports it:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from simplex.manifest import DeckManifest, MainSlide, Subsection
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
When the schema bumps `schema_version`, the web builder hard-fails on
|
|
143
|
+
unknown versions with a pointer at the `manim-simplex` upgrade. This
|
|
144
|
+
keeps the two repos honest about their contract.
|
|
145
|
+
|
|
146
|
+
## Why a separate distribution?
|
|
147
|
+
|
|
148
|
+
The plugin surface (mobjects + theme + entry-point + manifest schema)
|
|
149
|
+
is reusable independently of the lecture-portal pipeline. Splitting
|
|
150
|
+
them lets the plugin be a thin dependency for users who want to render
|
|
151
|
+
slides without pulling in Typer, watchfiles, Jinja, and the web
|
|
152
|
+
builder stack.
|
|
153
|
+
|
|
154
|
+
Python's PEP 420 implicit namespace packages merge the two distributions
|
|
155
|
+
at import time. Neither wheel ships `src/simplex/__init__.py`, so
|
|
156
|
+
`from simplex.engine import Remove` resolves regardless of which wheel
|
|
157
|
+
contributed the module.
|
|
158
|
+
|
|
159
|
+
## Development
|
|
160
|
+
|
|
161
|
+
Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
git clone https://github.com/shlomi-perles/manim-simplex.git
|
|
165
|
+
cd manim-simplex
|
|
166
|
+
uv sync --all-extras
|
|
167
|
+
uv run pre-commit install
|
|
168
|
+
uv run pytest -q
|
|
169
|
+
uv run ruff check .
|
|
170
|
+
uv run basedpyright
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Examples under `examples/` are runnable demo scenes; they double as
|
|
174
|
+
documentation and CI smoke tests:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv run manim -pql examples/hello_slide.py HelloSlide
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
Runnable demo scenes that double as integration smoke tests.
|
|
4
|
+
|
|
5
|
+
Each scene is intentionally small (single concept, ~30 LOC) and uses the
|
|
6
|
+
`manim-simplex` public API as a downstream user would.
|
|
7
|
+
|
|
8
|
+
## Running
|
|
9
|
+
|
|
10
|
+
From the repo root with the dev environment synced:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv run manim -pql examples/hello_slide.py HelloSlide
|
|
14
|
+
uv run manim -pql examples/theme_demo.py ThemeDemo
|
|
15
|
+
uv run manim -pql examples/glyph_map_demo.py GlyphMapDemo
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The `-pql` flag previews at low quality. Use `-pqh` for 1080p, `-qk` for
|
|
19
|
+
4K render-only.
|
|
20
|
+
|
|
21
|
+
## With manim-slides
|
|
22
|
+
|
|
23
|
+
To render as a slide deck (uses the `Slide` base class):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv run manim-slides render examples/hello_slide.py HelloSlide
|
|
27
|
+
uv run manim-slides present HelloSlide
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The plugin auto-activates via the `manim.plugins` entry-point as long as
|
|
31
|
+
the deck's `manim.cfg` declares `plugins = simplex`. For these examples
|
|
32
|
+
we keep a tiny `manim.cfg` next to them so they render with the Simplex
|
|
33
|
+
theme out of the box.
|