feat(lib): use and add more config option (#452)

* feat(lib): use and add more config option

Closes #441

* feat(lib): add support for more options and test them

* chore(docs): add attributes to documentation

* chore(docs): sort members by member type

* chore(docs): small improvements

* chore(docs): cleanup
This commit is contained in:
Jérome Eertmans
2024-09-05 14:08:10 +02:00
committed by GitHub
parent 87867762ea
commit a39a9c2bb1
9 changed files with 302 additions and 25 deletions

View File

@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `manim-slides checkhealth` command to easily obtain important information - Added `manim-slides checkhealth` command to easily obtain important information
for debug purposes. for debug purposes.
[#458](https://github.com/jeertmans/manim-slides/pull/458) [#458](https://github.com/jeertmans/manim-slides/pull/458)
- Added support for `disable_caching` and `flush_cache` options from Manim, and
also the possibility to configure them through class options.
[#452](https://github.com/jeertmans/manim-slides/pull/452)
(unreleased-chore)= (unreleased-chore)=
### Chore ### Chore

View File

@ -283,8 +283,7 @@ class ManimSlidesDirective(Directive):
# Rendering is skipped if the tag skip-manim is present, # Rendering is skipped if the tag skip-manim is present,
# or if we are making the pot-files # or if we are making the pot-files
should_skip = ( should_skip = (
"skip-manim-slides" self.state.document.settings.env.app.builder.tags.has("skip-manim-slides")
in self.state.document.settings.env.app.builder.tags.tags
or self.state.document.settings.env.app.builder.name == "gettext" or self.state.document.settings.env.app.builder.name == "gettext"
or "SKIP_MANIM_SLIDES" in os.environ or "SKIP_MANIM_SLIDES" in os.environ
) )

View File

@ -3,6 +3,7 @@ from __future__ import annotations
__all__ = ["BaseSlide"] __all__ = ["BaseSlide"]
import platform import platform
import shutil
from abc import abstractmethod from abc import abstractmethod
from collections.abc import MutableMapping, Sequence, ValuesView from collections.abc import MutableMapping, Sequence, ValuesView
from pathlib import Path from pathlib import Path
@ -32,6 +33,10 @@ LEFT: np.ndarray = np.array([-1.0, 0.0, 0.0])
class BaseSlide: class BaseSlide:
disable_caching: bool = False
flush_cache: bool = False
skip_reversing: bool = False
def __init__( def __init__(
self, *args: Any, output_folder: Path = FOLDER_PATH, **kwargs: Any self, *args: Any, output_folder: Path = FOLDER_PATH, **kwargs: Any
) -> None: ) -> None:
@ -170,11 +175,23 @@ class BaseSlide:
animations. You must still call :code:`self.add` or animations. You must still call :code:`self.add` or
play some animation that introduces each Mobject for play some animation that introduces each Mobject for
it to appear. The same applies when removing objects. it to appear. The same applies when removing objects.
.. seealso::
:attr:`canvas` for usage examples.
""" """
self._canvas.update(objects) self._canvas.update(objects)
def remove_from_canvas(self, *names: str) -> None: def remove_from_canvas(self, *names: str) -> None:
"""Remove objects from the canvas.""" """
Remove objects from the canvas.
:param names: The names of objects to remove.
.. seealso::
:attr:`canvas` for usage examples.
"""
for name in names: for name in names:
self._canvas.pop(name) self._canvas.pop(name)
@ -186,8 +203,12 @@ class BaseSlide:
@property @property
def mobjects_without_canvas(self) -> Sequence[Mobject]: def mobjects_without_canvas(self) -> Sequence[Mobject]:
""" """
Return the list of objects contained in the scene, minus those present in Return the list of Mobjects contained in the scene, minus those present in
the canvas. the canvas.
.. seealso::
:attr:`canvas` for usage examples.
""" """
return [ return [
mobject mobject
@ -275,7 +296,7 @@ class BaseSlide:
next slide is played. By default, this is the right arrow key. next slide is played. By default, this is the right arrow key.
:param args: :param args:
Positional arguments to be passed to Positional arguments passed to
:meth:`Scene.next_section<manim.scene.scene.Scene.next_section>`, :meth:`Scene.next_section<manim.scene.scene.Scene.next_section>`,
or ignored if `manimlib` API is used. or ignored if `manimlib` API is used.
:param loop: :param loop:
@ -284,27 +305,38 @@ class BaseSlide:
If set, next slide will play immediately play the next slide If set, next slide will play immediately play the next slide
upon terminating. upon terminating.
Note that this is only supported by ``manim-slides present`` .. warning::
Only supported by ``manim-slides present``
and ``manim-slides convert --to=html``. and ``manim-slides convert --to=html``.
:param playback_rate: :param playback_rate:
Playback rate at which the video is played. Playback rate at which the video is played.
Note that this is only supported by ``manim-slides present``. .. warning::
Only supported by ``manim-slides present``.
:param reversed_playback_rate: :param reversed_playback_rate:
Playback rate at which the reversed video is played. Playback rate at which the reversed video is played.
Note that this is only supported by ``manim-slides present``. .. warning::
Only supported by ``manim-slides present``.
:param notes: :param notes:
Presenter notes, in Markdown format. Presenter notes, in Markdown format.
Note that PowerPoint does not support Markdown. .. note::
PowerPoint does not support Markdown formatting,
so the text will be displayed as is.
Note that this is only supported by ``manim-slides present`` .. warning::
and ``manim-slides convert --to=html/pptx``.
Only supported by ``manim-slides present``,
``manim-slides convert --to=html`` and
``manim-slides convert --to=pptx``.
:param dedent_notes: :param dedent_notes:
If set, apply :func:`textwrap.dedent` to notes. If set, apply :func:`textwrap.dedent` to notes.
:param kwargs: :param kwargs:
Keyword arguments to be passed to Keyword arguments passed to
:meth:`Scene.next_section<manim.scene.scene.Scene.next_section>`, :meth:`Scene.next_section<manim.scene.scene.Scene.next_section>`,
or ignored if `manimlib` API is used. or ignored if `manimlib` API is used.
@ -445,11 +477,17 @@ class BaseSlide:
) )
) )
def _save_slides(self, use_cache: bool = True) -> None: def _save_slides(
self,
use_cache: bool = True,
flush_cache: bool = False,
skip_reversing: bool = False,
) -> None:
""" """
Save slides, optionally using cached files. Save slides, optionally using cached files.
Note that cached files only work with Manim. .. warning:
Caching files only work with Manim.
""" """
self._add_last_slide() self._add_last_slide()
@ -458,6 +496,9 @@ class BaseSlide:
scene_name = str(self) scene_name = str(self)
scene_files_folder = files_folder / scene_name scene_files_folder = files_folder / scene_name
if flush_cache and scene_files_folder.exists():
shutil.rmtree(scene_files_folder)
scene_files_folder.mkdir(parents=True, exist_ok=True) scene_files_folder.mkdir(parents=True, exist_ok=True)
files: list[Path] = self._partial_movie_files files: list[Path] = self._partial_movie_files
@ -492,6 +533,9 @@ class BaseSlide:
# We only reverse video if it was not present # We only reverse video if it was not present
if not use_cache or not rev_file.exists(): if not use_cache or not rev_file.exists():
if skip_reversing:
rev_file = dst_file
else:
reverse_video_file(dst_file, rev_file) reverse_video_file(dst_file, rev_file)
slides.append( slides.append(

View File

@ -13,6 +13,22 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
""" """
Inherits from :class:`Scene<manim.scene.scene.Scene>` and provide necessary tools Inherits from :class:`Scene<manim.scene.scene.Scene>` and provide necessary tools
for slides rendering. for slides rendering.
:param args: Positional arguments passed to scene object.
:param output_folder: Where the slide animation files should be written.
:param kwargs: Keyword arguments passed to scene object.
:cvar bool disable_caching: :data:`False`: Whether to disable the use of
cached animation files.
:cvar bool flush_cache: :data:`False`: Whether to flush the cache.
Unlike with Manim, flushing is performed before rendering.
:cvar bool skip_reversing: :data:`False`: Whether to generate reversed animations.
If set to :data:`False`, and no cached reversed animation
exists (or caching is disabled) for a given slide,
then the reversed animation will be simply the same
as the original one, i.e., ``rev_file = file``,
for the current slide config.
""" """
@property @property
@ -102,16 +118,29 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
) )
def render(self, *args: Any, **kwargs: Any) -> None: def render(self, *args: Any, **kwargs: Any) -> None:
"""MANIM render.""" """MANIM renderer."""
# We need to disable the caching limit since we rely on intermediate files # We need to disable the caching limit since we rely on intermediate files
max_files_cached = config["max_files_cached"] max_files_cached = config["max_files_cached"]
config["max_files_cached"] = float("inf") config["max_files_cached"] = float("inf")
flush_manim_cache = config["flush_cache"]
if flush_manim_cache:
# We need to postpone flushing *after* we saved slides
config["flush_cache"] = False
super().render(*args, **kwargs) super().render(*args, **kwargs)
config["max_files_cached"] = max_files_cached config["max_files_cached"] = max_files_cached
self._save_slides() self._save_slides(
use_cache=not (config["disable_caching"] or self.disable_caching),
flush_cache=(config["flush_cache"] or self.flush_cache),
skip_reversing=self.skip_reversing,
)
if flush_manim_cache:
self.renderer.file_writer.flush_cache_directory()
class ThreeDSlide(Slide, ThreeDScene): # type: ignore[misc] class ThreeDSlide(Slide, ThreeDScene): # type: ignore[misc]

View File

@ -62,7 +62,11 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
def run(self, *args: Any, **kwargs: Any) -> None: def run(self, *args: Any, **kwargs: Any) -> None:
"""MANIMGL renderer.""" """MANIMGL renderer."""
super().run(*args, **kwargs) super().run(*args, **kwargs)
self._save_slides(use_cache=False) self._save_slides(
use_cache=False,
flush_cache=self.flush_cache,
skip_reversing=self.skip_reversing,
)
class ThreeDSlide(Slide): class ThreeDSlide(Slide):

View File

@ -7,6 +7,7 @@
# all-features: true # all-features: true
# with-sources: false # with-sources: false
# generate-hashes: false # generate-hashes: false
# universal: false
-e file:. -e file:.
alabaster==1.0.0 alabaster==1.0.0
@ -48,10 +49,16 @@ click-default-group==1.2.4
# via manim-slides # via manim-slides
cloup==3.0.5 cloup==3.0.5
# via manim # via manim
colour==0.1.5
# via manimgl
comm==0.2.2 comm==0.2.2
# via ipykernel # via ipykernel
contourpy==1.3.0
# via matplotlib
coverage==7.6.1 coverage==7.6.1
# via pytest-cov # via pytest-cov
cycler==0.12.1
# via matplotlib
debugpy==1.8.5 debugpy==1.8.5
# via ipykernel # via ipykernel
decorator==5.1.1 decorator==5.1.1
@ -73,6 +80,8 @@ fastjsonschema==2.20.0
# via nbformat # via nbformat
filelock==3.15.4 filelock==3.15.4
# via virtualenv # via virtualenv
fonttools==4.53.1
# via matplotlib
furo==2024.8.6 furo==2024.8.6
# via manim-slides # via manim-slides
glcontext==3.0.0 glcontext==3.0.0
@ -90,8 +99,10 @@ ipykernel==6.29.5
ipython==8.26.0 ipython==8.26.0
# via ipykernel # via ipykernel
# via manim-slides # via manim-slides
# via manimgl
isosurfaces==0.1.2 isosurfaces==0.1.2
# via manim # via manim
# via manimgl
jedi==0.19.1 jedi==0.19.1
# via ipython # via ipython
jinja2==3.1.4 jinja2==3.1.4
@ -115,16 +126,22 @@ jupyter-core==5.7.2
# via nbformat # via nbformat
jupyterlab-pygments==0.3.0 jupyterlab-pygments==0.3.0
# via nbconvert # via nbconvert
kiwisolver==1.4.5
# via matplotlib
lxml==5.3.0 lxml==5.3.0
# via manim-slides # via manim-slides
# via python-pptx # via python-pptx
manim==0.18.1 manim==0.18.1
# via manim-slides # via manim-slides
manimgl==1.6.1
# via manim-slides
manimpango==0.5.0 manimpango==0.5.0
# via --override (workspace) # via --override (workspace)
# via manim # via manim
# via manimgl
mapbox-earcut==1.0.2 mapbox-earcut==1.0.2
# via manim # via manim
# via manimgl
markdown-it-py==3.0.0 markdown-it-py==3.0.0
# via mdit-py-plugins # via mdit-py-plugins
# via myst-parser # via myst-parser
@ -132,6 +149,8 @@ markdown-it-py==3.0.0
markupsafe==2.1.5 markupsafe==2.1.5
# via jinja2 # via jinja2
# via nbconvert # via nbconvert
matplotlib==3.9.2
# via manimgl
matplotlib-inline==0.1.7 matplotlib-inline==0.1.7
# via ipykernel # via ipykernel
# via ipython # via ipython
@ -143,9 +162,13 @@ mistune==3.0.2
# via nbconvert # via nbconvert
moderngl==5.11.1 moderngl==5.11.1
# via manim # via manim
# via manimgl
# via moderngl-window # via moderngl-window
moderngl-window==2.4.6 moderngl-window==2.4.6
# via manim # via manim
# via manimgl
mpmath==1.3.0
# via sympy
multipledispatch==1.0.0 multipledispatch==1.0.0
# via pyrr # via pyrr
myst-parser==4.0.0 myst-parser==4.0.0
@ -166,19 +189,21 @@ networkx==3.3
# via manim # via manim
nodeenv==1.9.1 nodeenv==1.9.1
# via pre-commit # via pre-commit
numpy==2.1.0 numpy==1.24.0
# via --override (workspace) # via --override (workspace)
# via ipython # via contourpy
# via isosurfaces # via isosurfaces
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
# via mapbox-earcut # via mapbox-earcut
# via matplotlib
# via moderngl-window # via moderngl-window
# via networkx
# via pyrr # via pyrr
# via scipy # via scipy
packaging==24.1 packaging==24.1
# via ipykernel # via ipykernel
# via matplotlib
# via nbconvert # via nbconvert
# via pytest # via pytest
# via qtpy # via qtpy
@ -194,6 +219,8 @@ pexpect==4.9.0
pillow==10.4.0 pillow==10.4.0
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
# via matplotlib
# via moderngl-window # via moderngl-window
# via python-pptx # via python-pptx
platformdirs==4.2.2 platformdirs==4.2.2
@ -231,15 +258,21 @@ pydantic-settings==2.4.0
# via bump-my-version # via bump-my-version
pydub==0.25.1 pydub==0.25.1
# via manim # via manim
# via manimgl
pyglet==2.0.17 pyglet==2.0.17
# via moderngl-window # via moderngl-window
pygments==2.18.0 pygments==2.18.0
# via furo # via furo
# via ipython # via ipython
# via manim # via manim
# via manimgl
# via nbconvert # via nbconvert
# via rich # via rich
# via sphinx # via sphinx
pyopengl==3.1.7
# via manimgl
pyparsing==3.1.4
# via matplotlib
pyqt6==6.7.1 pyqt6==6.7.1
# via manim-slides # via manim-slides
pyqt6-qt6==6.7.2 pyqt6-qt6==6.7.2
@ -271,11 +304,13 @@ pytest-qt==4.4.0
# via manim-slides # via manim-slides
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via jupyter-client # via jupyter-client
# via matplotlib
python-dotenv==1.0.1 python-dotenv==1.0.1
# via pydantic-settings # via pydantic-settings
python-pptx==1.0.2 python-pptx==1.0.2
# via manim-slides # via manim-slides
pyyaml==6.0.2 pyyaml==6.0.2
# via manimgl
# via myst-parser # via myst-parser
# via pre-commit # via pre-commit
pyzmq==26.2.0 pyzmq==26.2.0
@ -295,6 +330,7 @@ rich==13.7.1
# via bump-my-version # via bump-my-version
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
# via rich-click # via rich-click
rich-click==1.8.3 rich-click==1.8.3
# via bump-my-version # via bump-my-version
@ -305,8 +341,10 @@ rtoml==0.11.0
# via manim-slides # via manim-slides
scipy==1.14.1 scipy==1.14.1
# via manim # via manim
# via manimgl
screeninfo==0.8.1 screeninfo==0.8.1
# via manim # via manim
# via manimgl
setuptools==73.0.1 setuptools==73.0.1
shiboken6==6.7.2 shiboken6==6.7.2
# via pyside6 # via pyside6
@ -318,6 +356,7 @@ six==1.16.0
# via python-dateutil # via python-dateutil
skia-pathops==0.8.0.post1 skia-pathops==0.8.0.post1
# via manim # via manim
# via manimgl
snowballstemmer==2.2.0 snowballstemmer==2.2.0
# via sphinx # via sphinx
soupsieve==2.6 soupsieve==2.6
@ -357,6 +396,9 @@ stack-data==0.6.3
# via ipython # via ipython
svgelements==1.9.6 svgelements==1.9.6
# via manim # via manim
# via manimgl
sympy==1.13.2
# via manimgl
tinycss2==1.3.0 tinycss2==1.3.0
# via nbconvert # via nbconvert
tomlkit==0.13.2 tomlkit==0.13.2
@ -367,6 +409,7 @@ tornado==6.4.1
tqdm==4.66.5 tqdm==4.66.5
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
traitlets==5.14.3 traitlets==5.14.3
# via comm # via comm
# via ipykernel # via ipykernel
@ -379,6 +422,7 @@ traitlets==5.14.3
# via nbformat # via nbformat
# via nbsphinx # via nbsphinx
typing-extensions==4.12.2 typing-extensions==4.12.2
# via ipython
# via manim # via manim
# via pydantic # via pydantic
# via pydantic-core # via pydantic-core
@ -386,6 +430,8 @@ typing-extensions==4.12.2
# via rich-click # via rich-click
urllib3==2.2.2 urllib3==2.2.2
# via requests # via requests
validators==0.33.0
# via manimgl
virtualenv==20.26.3 virtualenv==20.26.3
# via pre-commit # via pre-commit
watchdog==4.0.2 watchdog==4.0.2

View File

@ -7,6 +7,7 @@
# all-features: true # all-features: true
# with-sources: false # with-sources: false
# generate-hashes: false # generate-hashes: false
# universal: false
-e file:. -e file:.
alabaster==1.0.0 alabaster==1.0.0
@ -41,10 +42,16 @@ click-default-group==1.2.4
# via manim-slides # via manim-slides
cloup==3.0.5 cloup==3.0.5
# via manim # via manim
colour==0.1.5
# via manimgl
comm==0.2.2 comm==0.2.2
# via ipykernel # via ipykernel
contourpy==1.3.0
# via matplotlib
coverage==7.6.1 coverage==7.6.1
# via pytest-cov # via pytest-cov
cycler==0.12.1
# via matplotlib
debugpy==1.8.5 debugpy==1.8.5
# via ipykernel # via ipykernel
decorator==5.1.1 decorator==5.1.1
@ -62,6 +69,8 @@ executing==2.0.1
# via stack-data # via stack-data
fastjsonschema==2.20.0 fastjsonschema==2.20.0
# via nbformat # via nbformat
fonttools==4.53.1
# via matplotlib
furo==2024.8.6 furo==2024.8.6
# via manim-slides # via manim-slides
glcontext==3.0.0 glcontext==3.0.0
@ -77,8 +86,10 @@ ipykernel==6.29.5
ipython==8.26.0 ipython==8.26.0
# via ipykernel # via ipykernel
# via manim-slides # via manim-slides
# via manimgl
isosurfaces==0.1.2 isosurfaces==0.1.2
# via manim # via manim
# via manimgl
jedi==0.19.1 jedi==0.19.1
# via ipython # via ipython
jinja2==3.1.4 jinja2==3.1.4
@ -102,16 +113,22 @@ jupyter-core==5.7.2
# via nbformat # via nbformat
jupyterlab-pygments==0.3.0 jupyterlab-pygments==0.3.0
# via nbconvert # via nbconvert
kiwisolver==1.4.5
# via matplotlib
lxml==5.3.0 lxml==5.3.0
# via manim-slides # via manim-slides
# via python-pptx # via python-pptx
manim==0.18.1 manim==0.18.1
# via manim-slides # via manim-slides
manimgl==1.6.1
# via manim-slides
manimpango==0.5.0 manimpango==0.5.0
# via --override (workspace) # via --override (workspace)
# via manim # via manim
# via manimgl
mapbox-earcut==1.0.2 mapbox-earcut==1.0.2
# via manim # via manim
# via manimgl
markdown-it-py==3.0.0 markdown-it-py==3.0.0
# via mdit-py-plugins # via mdit-py-plugins
# via myst-parser # via myst-parser
@ -119,6 +136,8 @@ markdown-it-py==3.0.0
markupsafe==2.1.5 markupsafe==2.1.5
# via jinja2 # via jinja2
# via nbconvert # via nbconvert
matplotlib==3.9.2
# via manimgl
matplotlib-inline==0.1.7 matplotlib-inline==0.1.7
# via ipykernel # via ipykernel
# via ipython # via ipython
@ -130,9 +149,13 @@ mistune==3.0.2
# via nbconvert # via nbconvert
moderngl==5.11.1 moderngl==5.11.1
# via manim # via manim
# via manimgl
# via moderngl-window # via moderngl-window
moderngl-window==2.4.6 moderngl-window==2.4.6
# via manim # via manim
# via manimgl
mpmath==1.3.0
# via sympy
multipledispatch==1.0.0 multipledispatch==1.0.0
# via pyrr # via pyrr
myst-parser==4.0.0 myst-parser==4.0.0
@ -151,19 +174,21 @@ nest-asyncio==1.6.0
# via ipykernel # via ipykernel
networkx==3.3 networkx==3.3
# via manim # via manim
numpy==2.1.0 numpy==1.24.0
# via --override (workspace) # via --override (workspace)
# via ipython # via contourpy
# via isosurfaces # via isosurfaces
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
# via mapbox-earcut # via mapbox-earcut
# via matplotlib
# via moderngl-window # via moderngl-window
# via networkx
# via pyrr # via pyrr
# via scipy # via scipy
packaging==24.1 packaging==24.1
# via ipykernel # via ipykernel
# via matplotlib
# via nbconvert # via nbconvert
# via pytest # via pytest
# via qtpy # via qtpy
@ -179,6 +204,8 @@ pexpect==4.9.0
pillow==10.4.0 pillow==10.4.0
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
# via matplotlib
# via moderngl-window # via moderngl-window
# via python-pptx # via python-pptx
platformdirs==4.2.2 platformdirs==4.2.2
@ -209,15 +236,21 @@ pydantic-extra-types==2.9.0
# via manim-slides # via manim-slides
pydub==0.25.1 pydub==0.25.1
# via manim # via manim
# via manimgl
pyglet==2.0.17 pyglet==2.0.17
# via moderngl-window # via moderngl-window
pygments==2.18.0 pygments==2.18.0
# via furo # via furo
# via ipython # via ipython
# via manim # via manim
# via manimgl
# via nbconvert # via nbconvert
# via rich # via rich
# via sphinx # via sphinx
pyopengl==3.1.7
# via manimgl
pyparsing==3.1.4
# via matplotlib
pyqt6==6.7.1 pyqt6==6.7.1
# via manim-slides # via manim-slides
pyqt6-qt6==6.7.2 pyqt6-qt6==6.7.2
@ -249,9 +282,11 @@ pytest-qt==4.4.0
# via manim-slides # via manim-slides
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via jupyter-client # via jupyter-client
# via matplotlib
python-pptx==1.0.2 python-pptx==1.0.2
# via manim-slides # via manim-slides
pyyaml==6.0.2 pyyaml==6.0.2
# via manimgl
# via myst-parser # via myst-parser
pyzmq==26.2.0 pyzmq==26.2.0
# via ipykernel # via ipykernel
@ -267,6 +302,7 @@ requests==2.32.3
rich==13.7.1 rich==13.7.1
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
rpds-py==0.20.0 rpds-py==0.20.0
# via jsonschema # via jsonschema
# via referencing # via referencing
@ -274,8 +310,10 @@ rtoml==0.11.0
# via manim-slides # via manim-slides
scipy==1.14.1 scipy==1.14.1
# via manim # via manim
# via manimgl
screeninfo==0.8.1 screeninfo==0.8.1
# via manim # via manim
# via manimgl
shiboken6==6.7.2 shiboken6==6.7.2
# via pyside6 # via pyside6
# via pyside6-addons # via pyside6-addons
@ -286,6 +324,7 @@ six==1.16.0
# via python-dateutil # via python-dateutil
skia-pathops==0.8.0.post1 skia-pathops==0.8.0.post1
# via manim # via manim
# via manimgl
snowballstemmer==2.2.0 snowballstemmer==2.2.0
# via sphinx # via sphinx
soupsieve==2.6 soupsieve==2.6
@ -325,6 +364,9 @@ stack-data==0.6.3
# via ipython # via ipython
svgelements==1.9.6 svgelements==1.9.6
# via manim # via manim
# via manimgl
sympy==1.13.2
# via manimgl
tinycss2==1.3.0 tinycss2==1.3.0
# via nbconvert # via nbconvert
tornado==6.4.1 tornado==6.4.1
@ -333,6 +375,7 @@ tornado==6.4.1
tqdm==4.66.5 tqdm==4.66.5
# via manim # via manim
# via manim-slides # via manim-slides
# via manimgl
traitlets==5.14.3 traitlets==5.14.3
# via comm # via comm
# via ipykernel # via ipykernel
@ -345,12 +388,15 @@ traitlets==5.14.3
# via nbformat # via nbformat
# via nbsphinx # via nbsphinx
typing-extensions==4.12.2 typing-extensions==4.12.2
# via ipython
# via manim # via manim
# via pydantic # via pydantic
# via pydantic-core # via pydantic-core
# via python-pptx # via python-pptx
urllib3==2.2.2 urllib3==2.2.2
# via requests # via requests
validators==0.33.0
# via manimgl
watchdog==4.0.2 watchdog==4.0.2
# via manim # via manim
wcwidth==0.2.13 wcwidth==0.2.13

View File

@ -38,3 +38,7 @@ class BasicSlide(Slide):
self.next_slide() self.next_slide()
self.zoom(other_text, []) self.zoom(other_text, [])
class BasicSlideSkipReversing(BasicSlide):
skip_reversing = True

View File

@ -97,6 +97,108 @@ def test_render_basic_slide(
assert local_presentation_config.resolution == presentation_config.resolution assert local_presentation_config.resolution == presentation_config.resolution
def test_clear_cache(
slides_file: Path,
) -> None:
runner = CliRunner()
with runner.isolated_filesystem() as tmp_dir:
local_media_folder = (
Path(tmp_dir)
/ "media"
/ "videos"
/ slides_file.stem
/ "480p15"
/ "partial_movie_files"
/ "BasicSlide"
)
local_slides_folder = Path(tmp_dir) / "slides"
assert not local_media_folder.exists()
assert not local_slides_folder.exists()
results = runner.invoke(render, [str(slides_file), "BasicSlide", "-ql"])
assert results.exit_code == 0, results
assert local_media_folder.is_dir() and list(local_media_folder.iterdir())
assert local_slides_folder.exists()
results = runner.invoke(
render, [str(slides_file), "BasicSlide", "-ql", "--flush_cache"]
)
assert results.exit_code == 0, results
assert local_media_folder.is_dir() and not list(local_media_folder.iterdir())
assert local_slides_folder.exists()
results = runner.invoke(
render, [str(slides_file), "BasicSlide", "-ql", "--disable_caching"]
)
assert results.exit_code == 0, results
assert local_media_folder.is_dir() and list(local_media_folder.iterdir())
assert local_slides_folder.exists()
results = runner.invoke(
render,
[
str(slides_file),
"BasicSlide",
"-ql",
"--disable_caching",
"--flush_cache",
],
)
assert results.exit_code == 0, results
assert local_media_folder.is_dir() and not list(local_media_folder.iterdir())
assert local_slides_folder.exists()
@pytest.mark.parametrize(
"renderer",
[
"--CE",
pytest.param(
"--GL",
marks=pytest.mark.skipif(
sys.version_info >= (3, 12),
reason="ManimGL requires numpy<1.25, which is outdated and Python < 3.12",
),
),
],
)
@pytest.mark.parametrize(
("klass", "skip_reversing"),
[("BasicSlide", False), ("BasicSlideSkipReversing", True)],
)
def test_skip_reversing(
renderer: str,
slides_file: Path,
manimgl_config: Path,
klass: str,
skip_reversing: bool,
) -> None:
runner = CliRunner()
with runner.isolated_filesystem() as tmp_dir:
shutil.copy(manimgl_config, tmp_dir)
results = runner.invoke(render, [renderer, str(slides_file), klass, "-ql"])
assert results.exit_code == 0, results
local_slides_folder = (Path(tmp_dir) / "slides").resolve(strict=True)
local_config_file = (local_slides_folder / f"{klass}.json").resolve(strict=True)
local_presentation_config = PresentationConfig.from_file(local_config_file)
for slide in local_presentation_config.slides:
if skip_reversing:
assert slide.file == slide.rev_file
else:
assert slide.file != slide.rev_file
def init_slide(cls: SlideType) -> Slide: def init_slide(cls: SlideType) -> Slide:
if issubclass(cls, CESlide): if issubclass(cls, CESlide):
return cls() return cls()