simplex-web 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.
Files changed (123) hide show
  1. simplex_web-0.2.0/.gitignore +41 -0
  2. simplex_web-0.2.0/LICENSE +21 -0
  3. simplex_web-0.2.0/PKG-INFO +166 -0
  4. simplex_web-0.2.0/README.md +121 -0
  5. simplex_web-0.2.0/pyproject.toml +139 -0
  6. simplex_web-0.2.0/src/simplex/README.md +32 -0
  7. simplex_web-0.2.0/src/simplex/cli/README.md +13 -0
  8. simplex_web-0.2.0/src/simplex/cli/__init__.py +5 -0
  9. simplex_web-0.2.0/src/simplex/cli/commands.py +384 -0
  10. simplex_web-0.2.0/src/simplex/deck/README.md +19 -0
  11. simplex_web-0.2.0/src/simplex/deck/__init__.py +7 -0
  12. simplex_web-0.2.0/src/simplex/deck/_template/assets/.gitkeep +0 -0
  13. simplex_web-0.2.0/src/simplex/deck/_template/assets/code/.gitkeep +0 -0
  14. simplex_web-0.2.0/src/simplex/deck/_template/assets/figures/.gitkeep +0 -0
  15. simplex_web-0.2.0/src/simplex/deck/_template/deck.toml +11 -0
  16. simplex_web-0.2.0/src/simplex/deck/_template/manim.cfg +3 -0
  17. simplex_web-0.2.0/src/simplex/deck/_template/notes.md +27 -0
  18. simplex_web-0.2.0/src/simplex/deck/_template/refs.bib +12 -0
  19. simplex_web-0.2.0/src/simplex/deck/_template/slides/__init__.py +7 -0
  20. simplex_web-0.2.0/src/simplex/deck/_template/slides/intro.py +21 -0
  21. simplex_web-0.2.0/src/simplex/deck/config.py +207 -0
  22. simplex_web-0.2.0/src/simplex/deck/registry.py +110 -0
  23. simplex_web-0.2.0/src/simplex/deck/scaffold.py +86 -0
  24. simplex_web-0.2.0/src/simplex/deck/section.py +40 -0
  25. simplex_web-0.2.0/src/simplex/engine/README.md +9 -0
  26. simplex_web-0.2.0/src/simplex/render/README.md +46 -0
  27. simplex_web-0.2.0/src/simplex/render/__init__.py +1 -0
  28. simplex_web-0.2.0/src/simplex/render/html.py +132 -0
  29. simplex_web-0.2.0/src/simplex/render/pdf.py +32 -0
  30. simplex_web-0.2.0/src/simplex/render/pptx.py +32 -0
  31. simplex_web-0.2.0/src/simplex/render/reconcile.py +350 -0
  32. simplex_web-0.2.0/src/simplex/render/runner.py +116 -0
  33. simplex_web-0.2.0/src/simplex/render/thumbnail.py +374 -0
  34. simplex_web-0.2.0/src/simplex/slides/README.md +9 -0
  35. simplex_web-0.2.0/src/simplex/slides/components/README.md +9 -0
  36. simplex_web-0.2.0/src/simplex/theme/README.md +9 -0
  37. simplex_web-0.2.0/src/simplex/web/README.md +33 -0
  38. simplex_web-0.2.0/src/simplex/web/__init__.py +1 -0
  39. simplex_web-0.2.0/src/simplex/web/bibliography.py +248 -0
  40. simplex_web-0.2.0/src/simplex/web/bibtex.py +129 -0
  41. simplex_web-0.2.0/src/simplex/web/builder.py +321 -0
  42. simplex_web-0.2.0/src/simplex/web/callouts.py +134 -0
  43. simplex_web-0.2.0/src/simplex/web/citations.py +118 -0
  44. simplex_web-0.2.0/src/simplex/web/equations.py +79 -0
  45. simplex_web-0.2.0/src/simplex/web/notes.py +135 -0
  46. simplex_web-0.2.0/src/simplex/web/refs.py +60 -0
  47. simplex_web-0.2.0/src/simplex/web/sidenotes.py +76 -0
  48. simplex_web-0.2.0/src/simplex/web/site_config.py +71 -0
  49. simplex_web-0.2.0/src/simplex/web/slide_ref.py +54 -0
  50. simplex_web-0.2.0/src/simplex/web/static/.gitkeep +0 -0
  51. simplex_web-0.2.0/src/simplex/web/static/README.md +23 -0
  52. simplex_web-0.2.0/src/simplex/web/static/fonts/lato/lato-latin-400-italic.woff2 +0 -0
  53. simplex_web-0.2.0/src/simplex/web/static/fonts/lato/lato-latin-400-normal.woff2 +0 -0
  54. simplex_web-0.2.0/src/simplex/web/static/fonts/lato/lato-latin-700-italic.woff2 +0 -0
  55. simplex_web-0.2.0/src/simplex/web/static/fonts/lato/lato-latin-700-normal.woff2 +0 -0
  56. simplex_web-0.2.0/src/simplex/web/static/fonts/lato/lato-latin-900-normal.woff2 +0 -0
  57. simplex_web-0.2.0/src/simplex/web/static/fonts/merriweather/merriweather-latin-400-italic.woff2 +0 -0
  58. simplex_web-0.2.0/src/simplex/web/static/fonts/merriweather/merriweather-latin-400-normal.woff2 +0 -0
  59. simplex_web-0.2.0/src/simplex/web/static/fonts/merriweather/merriweather-latin-700-italic.woff2 +0 -0
  60. simplex_web-0.2.0/src/simplex/web/static/fonts/merriweather/merriweather-latin-700-normal.woff2 +0 -0
  61. simplex_web-0.2.0/src/simplex/web/static/fonts/merriweather/merriweather-latin-900-normal.woff2 +0 -0
  62. simplex_web-0.2.0/src/simplex/web/static/htmx.min.js +1 -0
  63. simplex_web-0.2.0/src/simplex/web/static/katex/auto-render.min.js +1 -0
  64. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  65. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  66. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  67. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  68. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  69. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  70. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  71. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  72. simplex_web-0.2.0/src/simplex/web/static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  73. simplex_web-0.2.0/src/simplex/web/static/katex/katex.min.css +1 -0
  74. simplex_web-0.2.0/src/simplex/web/static/katex/katex.min.js +1 -0
  75. simplex_web-0.2.0/src/simplex/web/static/lucide/README.md +7 -0
  76. simplex_web-0.2.0/src/simplex/web/static/lucide/lucide.min.js +12 -0
  77. simplex_web-0.2.0/src/simplex/web/static/notes.js +68 -0
  78. simplex_web-0.2.0/src/simplex/web/static/reveal.js/reset.css +30 -0
  79. simplex_web-0.2.0/src/simplex/web/static/reveal.js/reveal.css +8 -0
  80. simplex_web-0.2.0/src/simplex/web/static/reveal.js/reveal.js +9 -0
  81. simplex_web-0.2.0/src/simplex/web/static/simplex.css +1870 -0
  82. simplex_web-0.2.0/src/simplex/web/static/tailwind.js +64 -0
  83. simplex_web-0.2.0/src/simplex/web/static/viewer.js +428 -0
  84. simplex_web-0.2.0/src/simplex/web/templates/README.md +19 -0
  85. simplex_web-0.2.0/src/simplex/web/templates/_carousel.html +117 -0
  86. simplex_web-0.2.0/src/simplex/web/templates/base.html +110 -0
  87. simplex_web-0.2.0/src/simplex/web/templates/deck.html +149 -0
  88. simplex_web-0.2.0/src/simplex/web/templates/index.html +20 -0
  89. simplex_web-0.2.0/src/simplex/web/templates/revealjs.html.j2 +374 -0
  90. simplex_web-0.2.0/src/simplex/web/templates/section.html +74 -0
  91. simplex_web-0.2.0/src/simplex/web/vendor.py +148 -0
  92. simplex_web-0.2.0/tests/README.md +19 -0
  93. simplex_web-0.2.0/tests/__init__.py +0 -0
  94. simplex_web-0.2.0/tests/cli/README.md +15 -0
  95. simplex_web-0.2.0/tests/cli/__init__.py +0 -0
  96. simplex_web-0.2.0/tests/cli/test_help.py +12 -0
  97. simplex_web-0.2.0/tests/cli/test_new.py +41 -0
  98. simplex_web-0.2.0/tests/cli/test_render.py +108 -0
  99. simplex_web-0.2.0/tests/deck/README.md +8 -0
  100. simplex_web-0.2.0/tests/deck/__init__.py +0 -0
  101. simplex_web-0.2.0/tests/deck/test_config.py +72 -0
  102. simplex_web-0.2.0/tests/deck/test_registry.py +76 -0
  103. simplex_web-0.2.0/tests/deck/test_scaffold.py +74 -0
  104. simplex_web-0.2.0/tests/deck/test_section.py +32 -0
  105. simplex_web-0.2.0/tests/engine/README.md +7 -0
  106. simplex_web-0.2.0/tests/render/README.md +7 -0
  107. simplex_web-0.2.0/tests/render/__init__.py +0 -0
  108. simplex_web-0.2.0/tests/render/test_html.py +96 -0
  109. simplex_web-0.2.0/tests/render/test_reconcile.py +177 -0
  110. simplex_web-0.2.0/tests/render/test_runner.py +92 -0
  111. simplex_web-0.2.0/tests/render/test_thumbnail.py +226 -0
  112. simplex_web-0.2.0/tests/theme/README.md +7 -0
  113. simplex_web-0.2.0/tests/web/README.md +18 -0
  114. simplex_web-0.2.0/tests/web/__init__.py +0 -0
  115. simplex_web-0.2.0/tests/web/test_bibliography.py +170 -0
  116. simplex_web-0.2.0/tests/web/test_builder.py +120 -0
  117. simplex_web-0.2.0/tests/web/test_callouts.py +103 -0
  118. simplex_web-0.2.0/tests/web/test_citations.py +72 -0
  119. simplex_web-0.2.0/tests/web/test_equations.py +74 -0
  120. simplex_web-0.2.0/tests/web/test_notes.py +38 -0
  121. simplex_web-0.2.0/tests/web/test_sidenotes.py +57 -0
  122. simplex_web-0.2.0/tests/web/test_site_config.py +62 -0
  123. simplex_web-0.2.0/tests/web/test_slide_ref.py +27 -0
@@ -0,0 +1,41 @@
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
+ .simplex_cache/
20
+ .mypy_cache/
21
+
22
+ # Manim output
23
+ media/
24
+ decks/**/slides/*.json
25
+ decks/**/slides/files/
26
+
27
+ # Generated site
28
+ site/
29
+
30
+ # Vendored web runtime assets (fetched on demand by simplex.web.vendor)
31
+ src/simplex/web/static/tailwind.js
32
+ src/simplex/web/static/htmx.min.js
33
+ src/simplex/web/static/katex/
34
+ src/simplex/web/static/reveal.js/
35
+ src/simplex/web/static/fonts/
36
+
37
+ # Editors
38
+ .idea/
39
+ .vscode/
40
+ *.swp
41
+ .DS_Store
@@ -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,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: simplex-web
3
+ Version: 0.2.0
4
+ Summary: Manim-slides presentation framework with a generated web portal.
5
+ Project-URL: Homepage, https://github.com/shlomi-perles/simplex
6
+ Project-URL: Issues, https://github.com/shlomi-perles/simplex/issues
7
+ Project-URL: Repository, https://github.com/shlomi-perles/simplex
8
+ Author: Shlomi Perles
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: animation,computer-science,education,lecture,manim,manim-slides,math,presentation,static-site
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
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 :: Internet :: WWW/HTTP :: Site Management
23
+ Classifier: Topic :: Multimedia :: Graphics
24
+ Classifier: Topic :: Multimedia :: Video
25
+ Classifier: Topic :: Scientific/Engineering :: Visualization
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.13
28
+ Requires-Dist: av>=15.0
29
+ Requires-Dist: jinja2>=3.1
30
+ Requires-Dist: manim-simplex>=0.2.0
31
+ Requires-Dist: manim-slides>=5.1.7
32
+ Requires-Dist: markdown-it-py>=3.0
33
+ Requires-Dist: mdit-py-plugins>=0.4
34
+ Requires-Dist: pillow>=11.0
35
+ Requires-Dist: platformdirs>=4.2
36
+ Requires-Dist: pydantic-settings>=2.3
37
+ Requires-Dist: pydantic>=2.7
38
+ Requires-Dist: pygments>=2.18
39
+ Requires-Dist: rich>=13.7
40
+ Requires-Dist: structlog>=24.1
41
+ Requires-Dist: tomli-w>=1.0
42
+ Requires-Dist: typer>=0.12
43
+ Requires-Dist: watchfiles>=0.24
44
+ Description-Content-Type: text/markdown
45
+
46
+ # Simplex
47
+
48
+ A Manim-slides presentation framework with a generated web portal.
49
+
50
+ Authors write **vanilla Manim** (`MathTex(...)`, `VGroup(...).arrange(RIGHT)`); Simplex configures defaults underneath via frozen theme tokens. A `simplex new` command scaffolds a new deck; `simplex build` renders every deck and produces a static portal for GitHub Pages.
51
+
52
+ ## The three repos
53
+
54
+ `simplex` is one of three packages that together make up the v0.2.0 toolkit:
55
+
56
+ | Repo | PyPI | Role |
57
+ |---|---|---|
58
+ | [`manim-simplex`](https://github.com/shlomi-perles/manim-simplex) | `manim-simplex` | The manim plugin: mobjects, theme, `BaseSlide`, the `manim.plugins` entry-point. |
59
+ | [`simplex`](https://github.com/shlomi-perles/simplex) | `simplex-web` | The platform: CLI, deck discovery, render orchestration, web builder. Depends on `manim-simplex`. |
60
+ | [`simplex-lectures-template`](https://github.com/shlomi-perles/simplex-lectures-template) | -- | GitHub Template. Pre-wired user lectures repo. |
61
+
62
+ The PyPI slot `simplex` was already taken by an unrelated project, and PyPI's
63
+ name-similarity guard rejects short variants, so this distribution publishes
64
+ as `simplex-web`. The *import* name is still
65
+ `simplex` -- both wheels ship `src/simplex/` **without** `__init__.py` and
66
+ Python's PEP 420 implicit namespace packages merge them at import time, so
67
+ `from simplex.engine import Remove` and `from simplex.cli.commands import app`
68
+ resolve regardless of which wheel ships the module.
69
+
70
+ ## Quick start
71
+
72
+ ```bash
73
+ # Install from PyPI:
74
+ pip install simplex-web
75
+
76
+ # Bootstrap a fresh checkout (Linux / macOS):
77
+ ./scripts/bootstrap.sh
78
+
79
+ # Or on Windows:
80
+ .\\scripts\\bootstrap.ps1
81
+
82
+ # Scaffold a new deck and render it:
83
+ uv run simplex new my-first-deck
84
+ uv run simplex render my-first-deck
85
+
86
+ # Generate the portal and preview it locally:
87
+ uv run simplex build
88
+ uv run simplex serve
89
+ ```
90
+
91
+ ## Repository layout
92
+
93
+ ```
94
+ simplex/
95
+ |-- src/simplex/ (no __init__.py -- PEP 420 namespace)
96
+ | |-- deck/ DeckConfig, discovery, scaffolder
97
+ | |-- render/ runner, reconcile, html/pdf/pptx, thumbnail
98
+ | |-- web/ markdown notes + Jinja portal + SSE reload
99
+ | `-- cli/ Typer entry point
100
+ |-- decks/ author content (one directory per deck)
101
+ `-- tests/
102
+
103
+ # Plugin half (mobjects, theme, slide bases) lives in manim-simplex.
104
+ ```
105
+
106
+ Every directory ships a short `README.md` (<=50 lines) covering *scope*, *public surface*, and *don'ts*. Only this root README is long-form.
107
+
108
+ ## Authoring a deck
109
+
110
+ A deck is three files plus optional assets:
111
+
112
+ ```
113
+ decks/my-deck/
114
+ |-- deck.toml slug, title, summary, tags, theme, scenes, quality
115
+ |-- slides.py vanilla Manim, subclassing simplex.slides.*
116
+ |-- notes.md English notes rendered into the portal
117
+ `-- assets/
118
+ ```
119
+
120
+ Inside `slides.py` you write plain Manim -- the framework's only contribution is the base class plus a pure `make_chrome` factory:
121
+
122
+ ```python
123
+ from manim import MathTex, ORIGIN, Write
124
+ from simplex.slides import BaseSlide, make_chrome
125
+ from simplex.theme.context import get_active_theme
126
+
127
+
128
+ class FermatLittleTheorem(BaseSlide):
129
+ def setup(self) -> None:
130
+ super().setup()
131
+ chrome = make_chrome(get_active_theme(), self.region, header="Fermat's little theorem")
132
+ self.add_to_canvas(**chrome.mobjects)
133
+ self.region = chrome.body_region
134
+
135
+ def construct(self) -> None:
136
+ eq = MathTex(r"a^{p-1} \equiv 1 \pmod p")
137
+ self.region.place(eq, ORIGIN)
138
+ self.play(Write(eq))
139
+ self.next_slide() # bare first call -> MAIN named "Fermat Little Theorem"
140
+ ```
141
+
142
+ No factories, no wrappers, no anti-corruption wall. The theme provides defaults, `self.region` provides bounded layout, and `clear_scene(exclude=...)` provides bulk fade-outs. Slide numbering / wall clock live in the RevealJS host (toggle via `[web]` in `deck.toml`), not the rendered frames.
143
+
144
+ ## Theme tokens
145
+
146
+ Presets are frozen `Theme` instances, not subclasses, so swapping the visual identity at runtime is one assignment:
147
+
148
+ ```python
149
+ from simplex.theme import active_theme, presets
150
+
151
+ with active_theme(presets.ACADEMIC_LIGHT):
152
+ # all slides constructed here pick up the light palette
153
+ ...
154
+ ```
155
+
156
+ LaTeX preamble lives on `theme.latex.preamble`. Fixed-width prose blocks use the `TexPage` mobject (default 20 cm, override via `width_cm=…` kwarg or a class attribute on a subclass).
157
+
158
+ ## Style + tooling
159
+
160
+ - Python **3.13+**, env + lockfile via **uv**, lint + format via **ruff**, types via **basedpyright --strict**.
161
+ - Configuration through frozen **Pydantic v2** models. No bare `dict[str, Any]`.
162
+ - See `STYLE.md` for the full rule set.
163
+
164
+ ## License
165
+
166
+ MIT.
@@ -0,0 +1,121 @@
1
+ # Simplex
2
+
3
+ A Manim-slides presentation framework with a generated web portal.
4
+
5
+ Authors write **vanilla Manim** (`MathTex(...)`, `VGroup(...).arrange(RIGHT)`); Simplex configures defaults underneath via frozen theme tokens. A `simplex new` command scaffolds a new deck; `simplex build` renders every deck and produces a static portal for GitHub Pages.
6
+
7
+ ## The three repos
8
+
9
+ `simplex` is one of three packages that together make up the v0.2.0 toolkit:
10
+
11
+ | Repo | PyPI | Role |
12
+ |---|---|---|
13
+ | [`manim-simplex`](https://github.com/shlomi-perles/manim-simplex) | `manim-simplex` | The manim plugin: mobjects, theme, `BaseSlide`, the `manim.plugins` entry-point. |
14
+ | [`simplex`](https://github.com/shlomi-perles/simplex) | `simplex-web` | The platform: CLI, deck discovery, render orchestration, web builder. Depends on `manim-simplex`. |
15
+ | [`simplex-lectures-template`](https://github.com/shlomi-perles/simplex-lectures-template) | -- | GitHub Template. Pre-wired user lectures repo. |
16
+
17
+ The PyPI slot `simplex` was already taken by an unrelated project, and PyPI's
18
+ name-similarity guard rejects short variants, so this distribution publishes
19
+ as `simplex-web`. The *import* name is still
20
+ `simplex` -- both wheels ship `src/simplex/` **without** `__init__.py` and
21
+ Python's PEP 420 implicit namespace packages merge them at import time, so
22
+ `from simplex.engine import Remove` and `from simplex.cli.commands import app`
23
+ resolve regardless of which wheel ships the module.
24
+
25
+ ## Quick start
26
+
27
+ ```bash
28
+ # Install from PyPI:
29
+ pip install simplex-web
30
+
31
+ # Bootstrap a fresh checkout (Linux / macOS):
32
+ ./scripts/bootstrap.sh
33
+
34
+ # Or on Windows:
35
+ .\\scripts\\bootstrap.ps1
36
+
37
+ # Scaffold a new deck and render it:
38
+ uv run simplex new my-first-deck
39
+ uv run simplex render my-first-deck
40
+
41
+ # Generate the portal and preview it locally:
42
+ uv run simplex build
43
+ uv run simplex serve
44
+ ```
45
+
46
+ ## Repository layout
47
+
48
+ ```
49
+ simplex/
50
+ |-- src/simplex/ (no __init__.py -- PEP 420 namespace)
51
+ | |-- deck/ DeckConfig, discovery, scaffolder
52
+ | |-- render/ runner, reconcile, html/pdf/pptx, thumbnail
53
+ | |-- web/ markdown notes + Jinja portal + SSE reload
54
+ | `-- cli/ Typer entry point
55
+ |-- decks/ author content (one directory per deck)
56
+ `-- tests/
57
+
58
+ # Plugin half (mobjects, theme, slide bases) lives in manim-simplex.
59
+ ```
60
+
61
+ Every directory ships a short `README.md` (<=50 lines) covering *scope*, *public surface*, and *don'ts*. Only this root README is long-form.
62
+
63
+ ## Authoring a deck
64
+
65
+ A deck is three files plus optional assets:
66
+
67
+ ```
68
+ decks/my-deck/
69
+ |-- deck.toml slug, title, summary, tags, theme, scenes, quality
70
+ |-- slides.py vanilla Manim, subclassing simplex.slides.*
71
+ |-- notes.md English notes rendered into the portal
72
+ `-- assets/
73
+ ```
74
+
75
+ Inside `slides.py` you write plain Manim -- the framework's only contribution is the base class plus a pure `make_chrome` factory:
76
+
77
+ ```python
78
+ from manim import MathTex, ORIGIN, Write
79
+ from simplex.slides import BaseSlide, make_chrome
80
+ from simplex.theme.context import get_active_theme
81
+
82
+
83
+ class FermatLittleTheorem(BaseSlide):
84
+ def setup(self) -> None:
85
+ super().setup()
86
+ chrome = make_chrome(get_active_theme(), self.region, header="Fermat's little theorem")
87
+ self.add_to_canvas(**chrome.mobjects)
88
+ self.region = chrome.body_region
89
+
90
+ def construct(self) -> None:
91
+ eq = MathTex(r"a^{p-1} \equiv 1 \pmod p")
92
+ self.region.place(eq, ORIGIN)
93
+ self.play(Write(eq))
94
+ self.next_slide() # bare first call -> MAIN named "Fermat Little Theorem"
95
+ ```
96
+
97
+ No factories, no wrappers, no anti-corruption wall. The theme provides defaults, `self.region` provides bounded layout, and `clear_scene(exclude=...)` provides bulk fade-outs. Slide numbering / wall clock live in the RevealJS host (toggle via `[web]` in `deck.toml`), not the rendered frames.
98
+
99
+ ## Theme tokens
100
+
101
+ Presets are frozen `Theme` instances, not subclasses, so swapping the visual identity at runtime is one assignment:
102
+
103
+ ```python
104
+ from simplex.theme import active_theme, presets
105
+
106
+ with active_theme(presets.ACADEMIC_LIGHT):
107
+ # all slides constructed here pick up the light palette
108
+ ...
109
+ ```
110
+
111
+ LaTeX preamble lives on `theme.latex.preamble`. Fixed-width prose blocks use the `TexPage` mobject (default 20 cm, override via `width_cm=…` kwarg or a class attribute on a subclass).
112
+
113
+ ## Style + tooling
114
+
115
+ - Python **3.13+**, env + lockfile via **uv**, lint + format via **ruff**, types via **basedpyright --strict**.
116
+ - Configuration through frozen **Pydantic v2** models. No bare `dict[str, Any]`.
117
+ - See `STYLE.md` for the full rule set.
118
+
119
+ ## License
120
+
121
+ MIT.
@@ -0,0 +1,139 @@
1
+ [build-system]
2
+ build-backend = "hatchling.build"
3
+ requires = ["hatchling"]
4
+
5
+ [dependency-groups]
6
+ dev = [
7
+ "pytest>=8",
8
+ "pytest-xdist>=3.5",
9
+ "syrupy>=4.6",
10
+ "ruff>=0.6",
11
+ "basedpyright>=1.13",
12
+ "pre-commit>=3.7",
13
+ ]
14
+
15
+ [project]
16
+ authors = [{name = "Shlomi Perles"}]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Environment :: Console",
20
+ "Intended Audience :: Education",
21
+ "Intended Audience :: Science/Research",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Operating System :: OS Independent",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3 :: Only",
27
+ "Topic :: Education",
28
+ "Topic :: Internet :: WWW/HTTP :: Site Management",
29
+ "Topic :: Multimedia :: Graphics",
30
+ "Topic :: Multimedia :: Video",
31
+ "Topic :: Scientific/Engineering :: Visualization",
32
+ "Typing :: Typed",
33
+ ]
34
+ dependencies = [
35
+ "manim-simplex>=0.2.0",
36
+ "manim-slides>=5.1.7",
37
+ "pydantic>=2.7",
38
+ "pydantic-settings>=2.3",
39
+ "typer>=0.12",
40
+ "rich>=13.7",
41
+ "structlog>=24.1",
42
+ "jinja2>=3.1",
43
+ "markdown-it-py>=3.0",
44
+ "mdit-py-plugins>=0.4",
45
+ "pygments>=2.18",
46
+ "platformdirs>=4.2",
47
+ "tomli-w>=1.0",
48
+ "watchfiles>=0.24",
49
+ # Already transitive via manim, but the thumbnail extractor imports them
50
+ # directly so we pin them here too.
51
+ "av>=15.0",
52
+ "pillow>=11.0",
53
+ ]
54
+ description = "Manim-slides presentation framework with a generated web portal."
55
+ keywords = [
56
+ "manim",
57
+ "manim-slides",
58
+ "animation",
59
+ "presentation",
60
+ "lecture",
61
+ "education",
62
+ "math",
63
+ "computer-science",
64
+ "static-site",
65
+ ]
66
+ license = "MIT"
67
+ license-files = ["LICENSE"]
68
+ # PyPI distribution name. The import name stays ``simplex`` (a PEP 420
69
+ # namespace shared with ``manim-simplex``); the wheel/sdist uses a longer
70
+ # brand name because the bare ``simplex`` slot is taken and short variants
71
+ # are rejected by PyPI's name-similarity guard.
72
+ name = "simplex-web"
73
+ readme = "README.md"
74
+ requires-python = ">=3.13"
75
+ version = "0.2.0"
76
+
77
+ [project.scripts]
78
+ simplex = "simplex.cli.commands:app"
79
+
80
+ [project.urls]
81
+ Homepage = "https://github.com/shlomi-perles/simplex"
82
+ Issues = "https://github.com/shlomi-perles/simplex/issues"
83
+ Repository = "https://github.com/shlomi-perles/simplex"
84
+
85
+ [tool.basedpyright]
86
+ include = ["src", "tests"]
87
+ pythonVersion = "3.13"
88
+ # Manim's 0.20.x type stubs are incomplete; mirror the same softening as
89
+ # manim-simplex so this repo's CI passes for the same upstream reasons.
90
+ reportArgumentType = "warning"
91
+ reportAssignmentType = "warning"
92
+ # manim-slides converters (PDF, PowerPoint, RevealJS) are Pydantic models
93
+ # with sensible defaults the stubs don't expose; reportCallIssue fires on
94
+ # every conversion call. Demote.
95
+ reportCallIssue = "warning"
96
+ reportInconsistentConstructor = "warning"
97
+ reportMissingTypeStubs = false
98
+ reportPrivateUsage = false
99
+ reportReturnType = "warning"
100
+ reportUnknownArgumentType = false
101
+ reportUnknownLambdaType = "warning"
102
+ reportUnknownMemberType = false
103
+ reportUnknownVariableType = false
104
+ typeCheckingMode = "strict"
105
+
106
+ [tool.hatch.build.targets.sdist]
107
+ artifacts = [
108
+ "src/simplex/web/static/fonts/**/*",
109
+ "src/simplex/web/static/htmx.min.js",
110
+ "src/simplex/web/static/katex/**/*",
111
+ "src/simplex/web/static/reveal.js/**/*",
112
+ "src/simplex/web/static/tailwind.js",
113
+ ]
114
+ only-include = [
115
+ "LICENSE",
116
+ "README.md",
117
+ "pyproject.toml",
118
+ "src",
119
+ "tests",
120
+ ]
121
+
122
+ [tool.hatch.build.targets.wheel]
123
+ # Ship the deck template and vendored runtime assets inside the wheel so
124
+ # ``simplex new`` and ``simplex build`` work from installed environments.
125
+ # Hatchling otherwise drops ignored files and dotfile placeholders by default.
126
+ artifacts = [
127
+ "src/simplex/deck/_template/**/*",
128
+ "src/simplex/deck/_template/**/.gitkeep",
129
+ "src/simplex/web/static/fonts/**/*",
130
+ "src/simplex/web/static/htmx.min.js",
131
+ "src/simplex/web/static/katex/**/*",
132
+ "src/simplex/web/static/reveal.js/**/*",
133
+ "src/simplex/web/static/tailwind.js",
134
+ ]
135
+ packages = ["src/simplex"]
136
+
137
+ [tool.pytest.ini_options]
138
+ addopts = "-q"
139
+ testpaths = ["tests"]
@@ -0,0 +1,32 @@
1
+ # src/simplex
2
+
3
+ The `simplex` distribution's half of the namespace: deck discovery,
4
+ render pipeline, web portal, and CLI. The plugin half (`simplex.plugin`,
5
+ `simplex.engine`, `simplex.theme`, `simplex.slides`) is shipped by the
6
+ `manim-simplex` distribution and merged into this same namespace at
7
+ import time via PEP 420.
8
+
9
+ This directory ships **no** `__init__.py`. Don't add one -- it would
10
+ shadow the implicit namespace and break the `manim-simplex` half.
11
+
12
+ ## Public surface (this distribution)
13
+
14
+ - `simplex.deck` -- `DeckConfig`, `discover`, `scaffold`
15
+ - `simplex.render` -- `runner`, `reconcile`, `html`, `pdf`, `pptx`, `thumbnail`
16
+ - `simplex.web` -- `builder`, `notes`, bibliography stack, templates, static, SSE reload
17
+ - `simplex.cli.commands:app` -- the Typer app behind `uv run simplex`
18
+
19
+ ## Public surface (re-exported from `manim-simplex`)
20
+
21
+ - `simplex.plugin:activate` -- the `manim.plugins` entry-point (set `plugins = simplex` in your `manim.cfg`)
22
+ - `simplex.slides` -- `BaseSlide`, `make_chrome`
23
+ - `simplex.theme` -- `Theme`, `WebPalette`, `active_theme`, `get_active_theme`, `presets`, `render_web_css`
24
+ - `simplex.engine` -- `apply_theme_defaults`, `Region`, `Remove`, `register_exit`, `set_exit_animation`, `clear_scene`, `SimplexSectionType`
25
+
26
+ ## Don't
27
+
28
+ - Don't add `src/simplex/__init__.py`. The namespace must stay implicit.
29
+ - Don't import `manim_editor`. The legacy package is deprecated and not a dependency.
30
+ - Don't wrap Manim constructors. Authors write vanilla Manim; the framework configures defaults underneath via `Mobject.set_default(...)`.
31
+ - Don't add a custom quality enum. Use `manim.constants.QUALITIES` keys directly.
32
+ - Don't bypass the plugin entry-point by setting `manim.config` from your scene. The plugin runs once at import time; that's the correct seam.
@@ -0,0 +1,13 @@
1
+ # cli/
2
+
3
+ Typer-based command surface exposed as `simplex` via `[project.scripts]`.
4
+
5
+ ## Public surface
6
+
7
+ - `app` -- Typer application (entry point: `simplex.cli.commands:app`)
8
+ - Commands: `new`, `render`, `build`, `serve`, `clean`, `doctor`
9
+
10
+ ## Don't
11
+
12
+ - Don't add business logic here. Commands are thin shells over `deck`, `render`, and `web`.
13
+ - Don't `os.chdir` outside of `serve`; that command intentionally enters `site/` to use `http.server`.
@@ -0,0 +1,5 @@
1
+ """CLI entry point."""
2
+
3
+ from simplex.cli.commands import app
4
+
5
+ __all__ = ["app"]