manim-simplex 0.2.0__tar.gz → 0.2.2__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 → manim_simplex-0.2.2}/CHANGELOG.md +6 -0
- manim_simplex-0.2.2/PKG-INFO +288 -0
- manim_simplex-0.2.2/README.md +255 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/pyproject.toml +2 -1
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/animations.py +6 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/mobjects/__init__.py +13 -1
- manim_simplex-0.2.2/src/simplex/mobjects/paper.py +456 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/pygments_style.py +2 -1
- manim_simplex-0.2.2/tests/mobjects/test_paper.py +136 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/uv.lock +22 -1
- manim_simplex-0.2.0/PKG-INFO +0 -214
- manim_simplex-0.2.0/README.md +0 -182
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/.gitignore +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/.pre-commit-config.yaml +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/.python-version +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/LICENSE +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/glyph_map_demo.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/hello_slide.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/manim.cfg +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/outline_slide.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/examples/theme_demo.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/ruff.toml +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/code.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/debug.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/defaults.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/dynamics.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/geometry.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/ghost_fade.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/glyph_map.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/region.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/scaling.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/engine/text.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/manifest.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/mobjects/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/mobjects/array.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/mobjects/graph.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/mobjects/outline.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/plugin.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/py.typed +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/section.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/slides/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/slides/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/slides/base.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/slides/chrome.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/slides/outline.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/context.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/presets.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/tokens.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/src/simplex/theme/web_css.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_animations.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_code.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_debug.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_dynamics.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_geometry.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_ghost_fade.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_glyph_map.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_region.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_scaling.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/engine/test_text.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/mobjects/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/mobjects/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/mobjects/test_graph.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/mobjects/test_outline.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/slides/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/slides/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/slides/test_base.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/slides/test_chrome.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/slides/test_outline.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/test_manifest.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/test_section.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/theme/README.md +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/theme/__init__.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/theme/test_tokens.py +0 -0
- {manim_simplex-0.2.0 → manim_simplex-0.2.2}/tests/theme/test_web_css.py +0 -0
|
@@ -6,6 +6,12 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.1] - 2026-05-24
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Highlight Pygments word operators in the Darcula code style.
|
|
14
|
+
|
|
9
15
|
## [0.2.0] - 2026-05-24
|
|
10
16
|
|
|
11
17
|
### Added
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: manim-simplex
|
|
3
|
+
Version: 0.2.2
|
|
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
|
+
Requires-Dist: pymupdf>=1.27.2.3
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# manim-simplex
|
|
35
|
+
|
|
36
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
37
|
+
[](https://pypi.org/project/manim-simplex/)
|
|
38
|
+
[](https://github.com/shlomi-perles/manim-simplex/actions/workflows/ci.yml)
|
|
39
|
+
[](https://github.com/shlomi-perles/manim-simplex/blob/main/LICENSE)
|
|
40
|
+
|
|
41
|
+
`manim-simplex` is the Manim plugin layer for Simplex: theme tokens,
|
|
42
|
+
slide bases, reusable mobjects, animation helpers, and the shared deck
|
|
43
|
+
manifest schema used by the Simplex web builder.
|
|
44
|
+
|
|
45
|
+
It is published as `manim-simplex` and exposes modules under the
|
|
46
|
+
implicit namespace package `simplex`.
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
- Python 3.13+
|
|
51
|
+
- Manim Community 0.20.1+
|
|
52
|
+
- manim-slides 5.1.7+
|
|
53
|
+
- Manim's system dependencies, including FFmpeg, Cairo, Pango, and a TeX
|
|
54
|
+
distribution when rendering TeX. See the Manim installation guide:
|
|
55
|
+
https://docs.manim.community/en/stable/installation.html
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install manim-simplex
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
With uv:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
uv add manim-simplex
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Verify that Manim can discover the plugin:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
python -m manim plugins -l
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The output should include `simplex`.
|
|
76
|
+
|
|
77
|
+
## Configure Manim
|
|
78
|
+
|
|
79
|
+
Enable the plugin in the `manim.cfg` next to your scenes or deck:
|
|
80
|
+
|
|
81
|
+
```ini
|
|
82
|
+
[CLI]
|
|
83
|
+
plugins = simplex
|
|
84
|
+
save_sections = True
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Manim imports `simplex.plugin` through the `manim.plugins` entry point.
|
|
88
|
+
The plugin applies the active Simplex theme to Manim defaults, registers
|
|
89
|
+
the Darcula Pygments style, sets the TeX template, sets the background
|
|
90
|
+
color, and enables section JSON output.
|
|
91
|
+
|
|
92
|
+
## Quick Start
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from manim import ORIGIN, MathTex, Write
|
|
96
|
+
|
|
97
|
+
from simplex.slides import BaseSlide, make_chrome
|
|
98
|
+
from simplex.theme import presets
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class HelloSlide(BaseSlide):
|
|
102
|
+
def setup(self) -> None:
|
|
103
|
+
super().setup()
|
|
104
|
+
chrome = make_chrome(
|
|
105
|
+
presets.DASTIMATOR_DARK,
|
|
106
|
+
self.region,
|
|
107
|
+
header="Hello, Simplex",
|
|
108
|
+
)
|
|
109
|
+
self.add_to_canvas(**chrome.mobjects)
|
|
110
|
+
self.region = chrome.body_region
|
|
111
|
+
|
|
112
|
+
def construct(self) -> None:
|
|
113
|
+
eq = MathTex(r"e^{i\pi} + 1 = 0")
|
|
114
|
+
self.region.place(eq, ORIGIN)
|
|
115
|
+
self.play(Write(eq))
|
|
116
|
+
self.next_slide() # first call -> MAIN named "Hello Slide"
|
|
117
|
+
|
|
118
|
+
consequence = MathTex(r"\therefore\ \cos\pi + i\sin\pi = -1")
|
|
119
|
+
self.region.place(consequence, ORIGIN)
|
|
120
|
+
self.play(Write(consequence))
|
|
121
|
+
self.next_slide() # later bare calls -> SUB stops
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Render as a slide deck:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
manim-slides render path/to/scene.py HelloSlide
|
|
128
|
+
manim-slides present HelloSlide
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Or, in a uv-managed project:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
uv run manim-slides render path/to/scene.py HelloSlide
|
|
135
|
+
uv run manim-slides present HelloSlide
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## What Ships Here
|
|
139
|
+
|
|
140
|
+
| Module | Public surface |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `simplex.plugin` | `activate()` entry point used by Manim. |
|
|
143
|
+
| `simplex.slides` | `BaseSlide`, `OutlineScene`, `OutlinePart`, `Chrome`, `make_chrome`. |
|
|
144
|
+
| `simplex.engine` | `Region`, `Remove`, `clear_scene`, `exit_for`, `register_exit`, `set_exit_animation`, `HighlightResult`, `apply_theme_defaults`. |
|
|
145
|
+
| `simplex.mobjects` | `Node`, `Edge`, `ArrayMob`, `ArrayEntry`, `ArrayPointer`, `OutlineProgressBar`. |
|
|
146
|
+
| `simplex.theme` | `Theme`, `Palette`, `Typography`, `Spacing`, `Motion`, `LatexProfile`, `WebPalette`, `active_theme`, `get_active_theme`, `presets`, `render_web_css`. |
|
|
147
|
+
| `simplex.section` | `SimplexSectionType`, the section strings written into Manim section JSON. |
|
|
148
|
+
| `simplex.manifest` | `DeckManifest`, `MainSlide`, `Subsection`, the Pydantic schema shared with `simplex-py`. |
|
|
149
|
+
|
|
150
|
+
Additional focused helpers live in submodules such as
|
|
151
|
+
`simplex.engine.glyph_map`, `simplex.engine.code`,
|
|
152
|
+
`simplex.engine.geometry`, `simplex.engine.text`, and
|
|
153
|
+
`simplex.engine.debug`.
|
|
154
|
+
|
|
155
|
+
## Slide Hierarchy
|
|
156
|
+
|
|
157
|
+
`BaseSlide.next_slide` writes Simplex section types into Manim's native
|
|
158
|
+
section JSON. The `simplex-py` web builder later reconciles those
|
|
159
|
+
sections with manim-slides metadata.
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
self.next_slide(name="Title") # MAIN slide named "Title"
|
|
163
|
+
self.next_slide() # first bare call: MAIN named after the class
|
|
164
|
+
self.next_slide() # later bare calls: SUB slide
|
|
165
|
+
self.next_slide(loop=True) # loop variant
|
|
166
|
+
self.next_slide(section_type="simplex.main.skip") # explicit override
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The first bare call is auto-named from the scene class, so
|
|
170
|
+
`DFSLecture` becomes `DFS Lecture`.
|
|
171
|
+
|
|
172
|
+
## Themes
|
|
173
|
+
|
|
174
|
+
Themes are frozen Pydantic models. The same theme instance drives Manim
|
|
175
|
+
defaults, TeX defaults, Pygments highlighting, and CSS variables for the
|
|
176
|
+
web portal.
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from manim import Tex
|
|
180
|
+
|
|
181
|
+
from simplex.theme import presets
|
|
182
|
+
from simplex.theme.context import active_theme
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
with active_theme(presets.ACADEMIC_LIGHT):
|
|
186
|
+
label = Tex("This Tex uses the academic light palette.")
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Available presets include `DASTIMATOR_DARK` and `ACADEMIC_LIGHT`.
|
|
190
|
+
|
|
191
|
+
## Outline Slides
|
|
192
|
+
|
|
193
|
+
`OutlineScene` turns typed `OutlinePart` objects into an animated agenda
|
|
194
|
+
slide with progress indicators.
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from manim import Circle, Square, Tex
|
|
198
|
+
|
|
199
|
+
from simplex.engine.text import Caption
|
|
200
|
+
from simplex.slides import OutlinePart, OutlineScene
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class Outline(OutlineScene):
|
|
204
|
+
def __init__(self, **kwargs):
|
|
205
|
+
super().__init__(
|
|
206
|
+
parts=[
|
|
207
|
+
OutlinePart(Tex("Research Question"), Caption("Question"), Circle()),
|
|
208
|
+
OutlinePart(Tex("Algorithms"), Caption("Algorithms"), Square()),
|
|
209
|
+
],
|
|
210
|
+
section_name="Outline",
|
|
211
|
+
**kwargs,
|
|
212
|
+
)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Examples
|
|
216
|
+
|
|
217
|
+
This repository includes runnable examples:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
uv run manim -pql examples/theme_demo.py ThemeDemo
|
|
221
|
+
uv run manim -pql examples/glyph_map_demo.py GlyphMapDemo
|
|
222
|
+
uv run manim-slides render examples/hello_slide.py HelloSlide
|
|
223
|
+
uv run manim-slides render examples/outline_slide.py OutlineDemo
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The examples directory has its own `manim.cfg`, so the Simplex plugin is
|
|
227
|
+
enabled when commands are run from the repository root.
|
|
228
|
+
|
|
229
|
+
## Relationship To `simplex-py`
|
|
230
|
+
|
|
231
|
+
Simplex is split into two PyPI distributions:
|
|
232
|
+
|
|
233
|
+
| Distribution | Import namespace | Purpose |
|
|
234
|
+
| --- | --- | --- |
|
|
235
|
+
| `manim-simplex` | `simplex.*` | Manim plugin, slide bases, theme, mobjects, manifest schema. |
|
|
236
|
+
| `simplex-py` | `simplex.*` | CLI, deck discovery, render orchestration, and static web portal. |
|
|
237
|
+
|
|
238
|
+
Both wheels intentionally contribute to the same PEP 420 namespace. This
|
|
239
|
+
package does not ship `simplex/__init__.py`; neither should downstream
|
|
240
|
+
extensions that want to share the namespace.
|
|
241
|
+
|
|
242
|
+
Install only `manim-simplex` if you want to render scenes and slides.
|
|
243
|
+
Install `simplex-py` later when you want the full lecture portal and CLI.
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
git clone https://github.com/shlomi-perles/manim-simplex.git
|
|
249
|
+
cd manim-simplex
|
|
250
|
+
uv sync --all-extras
|
|
251
|
+
uv run pre-commit install
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Useful checks:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
uv run ruff check .
|
|
258
|
+
uv run ruff format --check .
|
|
259
|
+
uv run basedpyright
|
|
260
|
+
uv run pytest -q
|
|
261
|
+
uv build
|
|
262
|
+
uvx twine check dist/*
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Run plugin smoke tests locally:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
uv run python -c "import simplex.plugin; simplex.plugin.activate(); print('ok')"
|
|
269
|
+
uv run manim plugins -l
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Release
|
|
273
|
+
|
|
274
|
+
Releases are published to PyPI by GitHub Actions through PyPI Trusted
|
|
275
|
+
Publishing. To release a new version:
|
|
276
|
+
|
|
277
|
+
1. Update `version` in `pyproject.toml`.
|
|
278
|
+
2. Move changelog entries under a dated release heading.
|
|
279
|
+
3. Commit the release prep.
|
|
280
|
+
4. Push an annotated tag such as `v0.2.1`.
|
|
281
|
+
|
|
282
|
+
The `Publish to PyPI` workflow builds an sdist and wheel, checks both
|
|
283
|
+
with Twine, uploads them as a GitHub artifact, and publishes to PyPI via
|
|
284
|
+
OIDC.
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,255 @@
|
|
|
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/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/shlomi-perles/manim-simplex/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
`manim-simplex` is the Manim plugin layer for Simplex: theme tokens,
|
|
9
|
+
slide bases, reusable mobjects, animation helpers, and the shared deck
|
|
10
|
+
manifest schema used by the Simplex web builder.
|
|
11
|
+
|
|
12
|
+
It is published as `manim-simplex` and exposes modules under the
|
|
13
|
+
implicit namespace package `simplex`.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Python 3.13+
|
|
18
|
+
- Manim Community 0.20.1+
|
|
19
|
+
- manim-slides 5.1.7+
|
|
20
|
+
- Manim's system dependencies, including FFmpeg, Cairo, Pango, and a TeX
|
|
21
|
+
distribution when rendering TeX. See the Manim installation guide:
|
|
22
|
+
https://docs.manim.community/en/stable/installation.html
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install manim-simplex
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With uv:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv add manim-simplex
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Verify that Manim can discover the plugin:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python -m manim plugins -l
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The output should include `simplex`.
|
|
43
|
+
|
|
44
|
+
## Configure Manim
|
|
45
|
+
|
|
46
|
+
Enable the plugin in the `manim.cfg` next to your scenes or deck:
|
|
47
|
+
|
|
48
|
+
```ini
|
|
49
|
+
[CLI]
|
|
50
|
+
plugins = simplex
|
|
51
|
+
save_sections = True
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Manim imports `simplex.plugin` through the `manim.plugins` entry point.
|
|
55
|
+
The plugin applies the active Simplex theme to Manim defaults, registers
|
|
56
|
+
the Darcula Pygments style, sets the TeX template, sets the background
|
|
57
|
+
color, and enables section JSON output.
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from manim import ORIGIN, MathTex, Write
|
|
63
|
+
|
|
64
|
+
from simplex.slides import BaseSlide, make_chrome
|
|
65
|
+
from simplex.theme import presets
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class HelloSlide(BaseSlide):
|
|
69
|
+
def setup(self) -> None:
|
|
70
|
+
super().setup()
|
|
71
|
+
chrome = make_chrome(
|
|
72
|
+
presets.DASTIMATOR_DARK,
|
|
73
|
+
self.region,
|
|
74
|
+
header="Hello, Simplex",
|
|
75
|
+
)
|
|
76
|
+
self.add_to_canvas(**chrome.mobjects)
|
|
77
|
+
self.region = chrome.body_region
|
|
78
|
+
|
|
79
|
+
def construct(self) -> None:
|
|
80
|
+
eq = MathTex(r"e^{i\pi} + 1 = 0")
|
|
81
|
+
self.region.place(eq, ORIGIN)
|
|
82
|
+
self.play(Write(eq))
|
|
83
|
+
self.next_slide() # first call -> MAIN named "Hello Slide"
|
|
84
|
+
|
|
85
|
+
consequence = MathTex(r"\therefore\ \cos\pi + i\sin\pi = -1")
|
|
86
|
+
self.region.place(consequence, ORIGIN)
|
|
87
|
+
self.play(Write(consequence))
|
|
88
|
+
self.next_slide() # later bare calls -> SUB stops
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Render as a slide deck:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
manim-slides render path/to/scene.py HelloSlide
|
|
95
|
+
manim-slides present HelloSlide
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or, in a uv-managed project:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run manim-slides render path/to/scene.py HelloSlide
|
|
102
|
+
uv run manim-slides present HelloSlide
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## What Ships Here
|
|
106
|
+
|
|
107
|
+
| Module | Public surface |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `simplex.plugin` | `activate()` entry point used by Manim. |
|
|
110
|
+
| `simplex.slides` | `BaseSlide`, `OutlineScene`, `OutlinePart`, `Chrome`, `make_chrome`. |
|
|
111
|
+
| `simplex.engine` | `Region`, `Remove`, `clear_scene`, `exit_for`, `register_exit`, `set_exit_animation`, `HighlightResult`, `apply_theme_defaults`. |
|
|
112
|
+
| `simplex.mobjects` | `Node`, `Edge`, `ArrayMob`, `ArrayEntry`, `ArrayPointer`, `OutlineProgressBar`. |
|
|
113
|
+
| `simplex.theme` | `Theme`, `Palette`, `Typography`, `Spacing`, `Motion`, `LatexProfile`, `WebPalette`, `active_theme`, `get_active_theme`, `presets`, `render_web_css`. |
|
|
114
|
+
| `simplex.section` | `SimplexSectionType`, the section strings written into Manim section JSON. |
|
|
115
|
+
| `simplex.manifest` | `DeckManifest`, `MainSlide`, `Subsection`, the Pydantic schema shared with `simplex-py`. |
|
|
116
|
+
|
|
117
|
+
Additional focused helpers live in submodules such as
|
|
118
|
+
`simplex.engine.glyph_map`, `simplex.engine.code`,
|
|
119
|
+
`simplex.engine.geometry`, `simplex.engine.text`, and
|
|
120
|
+
`simplex.engine.debug`.
|
|
121
|
+
|
|
122
|
+
## Slide Hierarchy
|
|
123
|
+
|
|
124
|
+
`BaseSlide.next_slide` writes Simplex section types into Manim's native
|
|
125
|
+
section JSON. The `simplex-py` web builder later reconciles those
|
|
126
|
+
sections with manim-slides metadata.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
self.next_slide(name="Title") # MAIN slide named "Title"
|
|
130
|
+
self.next_slide() # first bare call: MAIN named after the class
|
|
131
|
+
self.next_slide() # later bare calls: SUB slide
|
|
132
|
+
self.next_slide(loop=True) # loop variant
|
|
133
|
+
self.next_slide(section_type="simplex.main.skip") # explicit override
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The first bare call is auto-named from the scene class, so
|
|
137
|
+
`DFSLecture` becomes `DFS Lecture`.
|
|
138
|
+
|
|
139
|
+
## Themes
|
|
140
|
+
|
|
141
|
+
Themes are frozen Pydantic models. The same theme instance drives Manim
|
|
142
|
+
defaults, TeX defaults, Pygments highlighting, and CSS variables for the
|
|
143
|
+
web portal.
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from manim import Tex
|
|
147
|
+
|
|
148
|
+
from simplex.theme import presets
|
|
149
|
+
from simplex.theme.context import active_theme
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
with active_theme(presets.ACADEMIC_LIGHT):
|
|
153
|
+
label = Tex("This Tex uses the academic light palette.")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Available presets include `DASTIMATOR_DARK` and `ACADEMIC_LIGHT`.
|
|
157
|
+
|
|
158
|
+
## Outline Slides
|
|
159
|
+
|
|
160
|
+
`OutlineScene` turns typed `OutlinePart` objects into an animated agenda
|
|
161
|
+
slide with progress indicators.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from manim import Circle, Square, Tex
|
|
165
|
+
|
|
166
|
+
from simplex.engine.text import Caption
|
|
167
|
+
from simplex.slides import OutlinePart, OutlineScene
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class Outline(OutlineScene):
|
|
171
|
+
def __init__(self, **kwargs):
|
|
172
|
+
super().__init__(
|
|
173
|
+
parts=[
|
|
174
|
+
OutlinePart(Tex("Research Question"), Caption("Question"), Circle()),
|
|
175
|
+
OutlinePart(Tex("Algorithms"), Caption("Algorithms"), Square()),
|
|
176
|
+
],
|
|
177
|
+
section_name="Outline",
|
|
178
|
+
**kwargs,
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Examples
|
|
183
|
+
|
|
184
|
+
This repository includes runnable examples:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
uv run manim -pql examples/theme_demo.py ThemeDemo
|
|
188
|
+
uv run manim -pql examples/glyph_map_demo.py GlyphMapDemo
|
|
189
|
+
uv run manim-slides render examples/hello_slide.py HelloSlide
|
|
190
|
+
uv run manim-slides render examples/outline_slide.py OutlineDemo
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The examples directory has its own `manim.cfg`, so the Simplex plugin is
|
|
194
|
+
enabled when commands are run from the repository root.
|
|
195
|
+
|
|
196
|
+
## Relationship To `simplex-py`
|
|
197
|
+
|
|
198
|
+
Simplex is split into two PyPI distributions:
|
|
199
|
+
|
|
200
|
+
| Distribution | Import namespace | Purpose |
|
|
201
|
+
| --- | --- | --- |
|
|
202
|
+
| `manim-simplex` | `simplex.*` | Manim plugin, slide bases, theme, mobjects, manifest schema. |
|
|
203
|
+
| `simplex-py` | `simplex.*` | CLI, deck discovery, render orchestration, and static web portal. |
|
|
204
|
+
|
|
205
|
+
Both wheels intentionally contribute to the same PEP 420 namespace. This
|
|
206
|
+
package does not ship `simplex/__init__.py`; neither should downstream
|
|
207
|
+
extensions that want to share the namespace.
|
|
208
|
+
|
|
209
|
+
Install only `manim-simplex` if you want to render scenes and slides.
|
|
210
|
+
Install `simplex-py` later when you want the full lecture portal and CLI.
|
|
211
|
+
|
|
212
|
+
## Development
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
git clone https://github.com/shlomi-perles/manim-simplex.git
|
|
216
|
+
cd manim-simplex
|
|
217
|
+
uv sync --all-extras
|
|
218
|
+
uv run pre-commit install
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Useful checks:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
uv run ruff check .
|
|
225
|
+
uv run ruff format --check .
|
|
226
|
+
uv run basedpyright
|
|
227
|
+
uv run pytest -q
|
|
228
|
+
uv build
|
|
229
|
+
uvx twine check dist/*
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Run plugin smoke tests locally:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
uv run python -c "import simplex.plugin; simplex.plugin.activate(); print('ok')"
|
|
236
|
+
uv run manim plugins -l
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Release
|
|
240
|
+
|
|
241
|
+
Releases are published to PyPI by GitHub Actions through PyPI Trusted
|
|
242
|
+
Publishing. To release a new version:
|
|
243
|
+
|
|
244
|
+
1. Update `version` in `pyproject.toml`.
|
|
245
|
+
2. Move changelog entries under a dated release heading.
|
|
246
|
+
3. Commit the release prep.
|
|
247
|
+
4. Push an annotated tag such as `v0.2.1`.
|
|
248
|
+
|
|
249
|
+
The `Publish to PyPI` workflow builds an sdist and wheel, checks both
|
|
250
|
+
with Twine, uploads them as a GitHub artifact, and publishes to PyPI via
|
|
251
|
+
OIDC.
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -33,6 +33,7 @@ dependencies = [
|
|
|
33
33
|
"manim-slides>=5.1.7",
|
|
34
34
|
"pydantic>=2.7",
|
|
35
35
|
"pygments>=2.18",
|
|
36
|
+
"pymupdf>=1.27.2.3",
|
|
36
37
|
]
|
|
37
38
|
description = "Manim plugin: theme tokens, mobjects, slide hierarchy, deck manifest schema."
|
|
38
39
|
keywords = [
|
|
@@ -50,7 +51,7 @@ license-files = ["LICENSE"]
|
|
|
50
51
|
name = "manim-simplex"
|
|
51
52
|
readme = "README.md"
|
|
52
53
|
requires-python = ">=3.13"
|
|
53
|
-
version = "0.2.
|
|
54
|
+
version = "0.2.2"
|
|
54
55
|
|
|
55
56
|
[project.entry-points."manim.plugins"]
|
|
56
57
|
simplex = "simplex.plugin:activate"
|
|
@@ -66,10 +66,16 @@ class _DefaultRegistry:
|
|
|
66
66
|
VMobject,
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
+
from simplex.mobjects.paper import DismissPaper, Paper
|
|
70
|
+
|
|
69
71
|
def fade_with_drift(m: Any, **kw: Any) -> Any:
|
|
70
72
|
return FadeOut(m, shift=0.1 * DOWN, **kw)
|
|
71
73
|
|
|
74
|
+
def paper_exit(m: Any, **kw: Any) -> Any:
|
|
75
|
+
return DismissPaper(m, **kw)
|
|
76
|
+
|
|
72
77
|
return {
|
|
78
|
+
Paper: paper_exit,
|
|
73
79
|
Tex: Unwrite,
|
|
74
80
|
MathTex: Unwrite,
|
|
75
81
|
Text: Unwrite,
|
|
@@ -9,5 +9,17 @@ slide system.
|
|
|
9
9
|
from simplex.mobjects.array import ArrayEntry, ArrayMob, ArrayPointer
|
|
10
10
|
from simplex.mobjects.graph import Edge, Node
|
|
11
11
|
from simplex.mobjects.outline import OutlineProgressBar
|
|
12
|
+
from simplex.mobjects.paper import DismissPaper, Paper, PickPage, ShowPaper
|
|
12
13
|
|
|
13
|
-
__all__ = [
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ArrayEntry",
|
|
16
|
+
"ArrayMob",
|
|
17
|
+
"ArrayPointer",
|
|
18
|
+
"DismissPaper",
|
|
19
|
+
"Edge",
|
|
20
|
+
"Node",
|
|
21
|
+
"OutlineProgressBar",
|
|
22
|
+
"Paper",
|
|
23
|
+
"PickPage",
|
|
24
|
+
"ShowPaper",
|
|
25
|
+
]
|