From 806b7d00f6becdd719e6de91f04cad3c55a61501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Thu, 24 Aug 2023 13:22:04 +0200 Subject: [PATCH 001/194] fix(lib): correctly format enums on Python>=3.11 (#257) Closes #256 fix(tests): update tests and fix chore(lib): simplify fix and more tests chore(docs): document patch --- CHANGELOG.md | 10 ++++ manim_slides/convert.py | 45 ++++++++------- tests/test_convert.py | 122 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 156 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c161df6..8500bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,16 @@ In an effort to better document changes, this CHANGELOG document is now created. `REWIND` to `REPLAY`. [#243](https://github.com/jeertmans/manim-slides/pull/243) +### Fixed + +- Patched enums in `manim_slides/convert.py` to correctly call `str`'s + `__str__` method, and not the `Enum` one. + This bug was discovered by + [@alexanderskulikov](https://github.com/alexanderskulikov) in + [#253](https://github.com/jeertmans/manim-slides/discussions/253), caused by + Python 3.11's change in how `Enum` work. + [#257](https://github.com/jeertmans/manim-slides/pull/257). + ### Removed - Removed `--start-at-animation-number` option from `manim-slides present`. diff --git a/manim_slides/convert.py b/manim_slides/convert.py index 549a085..ab07ae1 100644 --- a/manim_slides/convert.py +++ b/manim_slides/convert.py @@ -140,43 +140,48 @@ class Str(str): def __str__(self) -> str: """Ensures that the string is correctly quoted.""" if self in ["true", "false", "null"]: - return super().__str__() + return self else: return f"'{super().__str__()}'" +class StrEnum(Enum): + def __str__(self) -> str: + return str(self.value) + + Function = str # Basically, anything -class JsTrue(str, Enum): +class JsTrue(str, StrEnum): true = "true" -class JsFalse(str, Enum): +class JsFalse(str, StrEnum): false = "false" -class JsBool(Str, Enum): # type: ignore +class JsBool(Str, StrEnum): # type: ignore true = "true" false = "false" -class JsNull(Str, Enum): # type: ignore +class JsNull(Str, StrEnum): # type: ignore null = "null" -class ControlsLayout(Str, Enum): # type: ignore +class ControlsLayout(Str, StrEnum): # type: ignore edges = "edges" bottom_right = "bottom-right" -class ControlsBackArrows(Str, Enum): # type: ignore +class ControlsBackArrows(Str, StrEnum): # type: ignore faded = "faded" hidden = "hidden" visibly = "visibly" -class SlideNumber(Str, Enum): # type: ignore +class SlideNumber(Str, StrEnum): # type: ignore true = "true" false = "false" hdotv = "h.v" @@ -185,24 +190,24 @@ class SlideNumber(Str, Enum): # type: ignore candt = "c/t" -class ShowSlideNumber(Str, Enum): # type: ignore +class ShowSlideNumber(Str, StrEnum): # type: ignore all = "all" print = "print" speaker = "speaker" -class KeyboardCondition(Str, Enum): # type: ignore +class KeyboardCondition(Str, StrEnum): # type: ignore null = "null" focused = "focused" -class NavigationMode(Str, Enum): # type: ignore +class NavigationMode(Str, StrEnum): # type: ignore default = "default" linear = "linear" grid = "grid" -class AutoPlayMedia(Str, Enum): # type: ignore +class AutoPlayMedia(Str, StrEnum): # type: ignore null = "null" true = "true" false = "false" @@ -211,25 +216,25 @@ class AutoPlayMedia(Str, Enum): # type: ignore PreloadIframes = AutoPlayMedia -class AutoAnimateMatcher(Str, Enum): # type: ignore +class AutoAnimateMatcher(Str, StrEnum): # type: ignore null = "null" -class AutoAnimateEasing(Str, Enum): # type: ignore +class AutoAnimateEasing(Str, StrEnum): # type: ignore ease = "ease" AutoSlide = Union[PositiveInt, JsFalse] -class AutoSlideMethod(Str, Enum): # type: ignore +class AutoSlideMethod(Str, StrEnum): # type: ignore null = "null" MouseWheel = Union[JsNull, float] -class Transition(Str, Enum): # type: ignore +class Transition(Str, StrEnum): # type: ignore none = "none" fade = "fade" slide = "slide" @@ -238,13 +243,13 @@ class Transition(Str, Enum): # type: ignore zoom = "zoom" -class TransitionSpeed(Str, Enum): # type: ignore +class TransitionSpeed(Str, StrEnum): # type: ignore default = "default" fast = "fast" slow = "slow" -class BackgroundSize(Str, Enum): # type: ignore +class BackgroundSize(Str, StrEnum): # type: ignore # From: https://developer.mozilla.org/en-US/docs/Web/CSS/background-size # TODO: support more background size contain = "contain" @@ -254,11 +259,11 @@ class BackgroundSize(Str, Enum): # type: ignore BackgroundTransition = Transition -class Display(Str, Enum): # type: ignore +class Display(Str, StrEnum): # type: ignore block = "block" -class RevealTheme(str, Enum): +class RevealTheme(str, StrEnum): black = "black" white = "white" league = "league" diff --git a/tests/test_convert.py b/tests/test_convert.py index 4e9142e..e3b2c83 100644 --- a/tests/test_convert.py +++ b/tests/test_convert.py @@ -1,6 +1,126 @@ +from enum import EnumMeta + import pytest -from manim_slides.convert import PDF, Converter, PowerPoint, RevealJS +from manim_slides.convert import ( + PDF, + AutoAnimateEasing, + AutoAnimateMatcher, + AutoPlayMedia, + AutoSlideMethod, + BackgroundSize, + BackgroundTransition, + ControlsBackArrows, + ControlsLayout, + Converter, + Display, + JsBool, + JsFalse, + JsNull, + JsTrue, + KeyboardCondition, + NavigationMode, + PowerPoint, + PreloadIframes, + RevealJS, + RevealTheme, + ShowSlideNumber, + SlideNumber, + Transition, + TransitionSpeed, +) + + +@pytest.mark.parametrize( + ("enum_type",), + [ + (JsTrue,), + (JsFalse,), + (JsBool,), + (JsNull,), + (ControlsLayout,), + (ControlsBackArrows,), + (SlideNumber,), + (ShowSlideNumber,), + (KeyboardCondition,), + (NavigationMode,), + (AutoPlayMedia,), + (PreloadIframes,), + (AutoAnimateMatcher,), + (AutoAnimateEasing,), + (AutoSlideMethod,), + (Transition,), + (TransitionSpeed,), + (BackgroundSize,), + (BackgroundTransition,), + (Display,), + (RevealTheme,), + ], +) +def test_format_enum(enum_type: EnumMeta) -> None: + for enum in enum_type: # type: ignore[var-annotated] + expected = str(enum) + got = f"{enum}" + + assert expected == got + + got = "{enum}".format(enum=enum) + + assert expected == got + + got = format(enum, "") + + assert expected == got + + +@pytest.mark.parametrize( + ("enum_type",), + [ + (ControlsLayout,), + (ControlsBackArrows,), + (SlideNumber,), + (ShowSlideNumber,), + (KeyboardCondition,), + (NavigationMode,), + (AutoPlayMedia,), + (PreloadIframes,), + (AutoAnimateMatcher,), + (AutoAnimateEasing,), + (AutoSlideMethod,), + (Transition,), + (TransitionSpeed,), + (BackgroundSize,), + (BackgroundTransition,), + (Display,), + ], +) +def test_quoted_enum(enum_type: EnumMeta) -> None: + for enum in enum_type: # type: ignore[var-annotated] + if enum in ["true", "false", "null"]: + continue + + expected = "'" + enum.value + "'" + got = str(enum) + + assert expected == got + + +@pytest.mark.parametrize( + ("enum_type",), + [ + (JsTrue,), + (JsFalse,), + (JsBool,), + (JsNull,), + (RevealTheme,), + ], +) +def test_unquoted_enum(enum_type: EnumMeta) -> None: + for enum in enum_type: # type: ignore[var-annotated] + expected = enum.value + got = str(enum) + + assert expected == got class TestConverter: From 0f07d36f52d7c96f9593df72128cb393e19167b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Mon, 28 Aug 2023 17:09:19 +0200 Subject: [PATCH 002/194] fix(deps): patch color for future manim versions (#255) --- manim_slides/slide.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/manim_slides/slide.py b/manim_slides/slide.py index 5faedaa..0237f56 100644 --- a/manim_slides/slide.py +++ b/manim_slides/slide.py @@ -83,7 +83,11 @@ class Slide(Scene): # type:ignore if MANIMGL: return self.camera_config["background_color"].hex # type: ignore else: - return config["background_color"].hex # type: ignore + color = config["background_color"] + if hex_color := getattr(color, "hex", None): + return hex_color # type: ignore + else: # manim>=0.18, see https://github.com/ManimCommunity/manim/pull/3020 + return color.to_hex() # type: ignore @property def __resolution(self) -> Tuple[int, int]: From 9a3a343231ddee37ce976819ed43e287ef787116 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:50:56 +0200 Subject: [PATCH 003/194] [pre-commit.ci] pre-commit autoupdate (#260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.0.285 → v0.0.286](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.285...v0.0.286) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9d797e..88e6117 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.285 + rev: v0.0.286 hooks: - id: ruff args: [--fix] From bb5b294f40730feea687dc43a87bb2435bcfd5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Tue, 29 Aug 2023 16:23:54 +0200 Subject: [PATCH 004/194] feat(lib): Sphinx directive can now read files (#261) * feat(lib): Sphinx directive can now read files You can optionally read a file instead of the Sphinx directive's content * fix(lib): rst syntax and docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .github/workflows/pages.yml | 16 ++------ CHANGELOG.md | 3 ++ docs/source/index.md | 10 ++--- docs/source/reference/examples.md | 18 ++++++--- manim_slides/docs/manim_slides_directive.py | 42 +++++++++++++++++---- 5 files changed, 57 insertions(+), 32 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index b8b6975..9a3cb25 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -56,18 +56,8 @@ jobs: id: cache-media-restore uses: actions/cache/restore@v3 with: - path: media - key: ${{ runner.os }}-media - - name: Build animations - run: | - poetry run manim example.py ConvertExample BasicExample ThreeDExample - - name: Convert animations to HTML slides - run: | - poetry run manim-slides convert -v DEBUG ConvertExample docs/source/_static/slides.html -ccontrols=true - poetry run manim-slides convert -v DEBUG BasicExample docs/source/_static/basic_example.html -ccontrols=true - poetry run manim-slides convert -v DEBUG ThreeDExample docs/source/_static/three_d_example.html -ccontrols=true - - name: Show docs/source/_static/ dir content (video only) - run: tree -L 3 docs/source/_static/ -P '*.mp4' + path: docs/media + key: ${{ runner.os }}-docs-media - name: Clear cache run: | gh extension install actions/gh-actions-cache @@ -78,7 +68,7 @@ jobs: id: cache-media-save uses: actions/cache/save@v3 with: - path: media + path: docs/media key: ${{ steps.cache-media-restore.outputs.cache-primary-key }} - name: Build docs run: cd docs && poetry run make html diff --git a/CHANGELOG.md b/CHANGELOG.md index 8500bdc..c06d7fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ In an effort to better document changes, this CHANGELOG document is now created. - Added a full screen key binding (defaults to F) in the presenter. [#243](https://github.com/jeertmans/manim-slides/pull/243) +- Added support for including code from a file in Manim Slides + Sphinx directive. + [#261](https://github.com/jeertmans/manim-slides/pull/261) ### Changed diff --git a/docs/source/index.md b/docs/source/index.md index 1edc758..95f0b24 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -28,11 +28,11 @@ In a [very few steps](./quickstart), you can create slides and present them eith Slide through the demo below to get a quick glimpse on what you can do with Manim Slides. - - - -
- +```{eval-rst} +.. manim-slides:: ../../example.py:ConvertExample + :hide_source: + :quality: high +``` ```{toctree} :hidden: diff --git a/docs/source/reference/examples.md b/docs/source/reference/examples.md index b5685cf..724a366 100644 --- a/docs/source/reference/examples.md +++ b/docs/source/reference/examples.md @@ -29,9 +29,11 @@ where `-ccontrols=true` indicates that we want to display the blue navigation ar Basic example from quickstart. -
- ```{eval-rst} +.. manim-slides: ../../../example.py:BasicExample + :hide_source: + :quality: high + .. literalinclude:: ../../../example.py :language: python :linenos: @@ -42,11 +44,13 @@ Basic example from quickstart. Example using 3D camera. As Manim and ManimGL handle 3D differently, definitions are slightly different. -
- ### With Manim ```{eval-rst} +.. manim-slides: ../../../example.py:ThreeDExample + :hide_source: + :quality: high + .. literalinclude:: ../../../example.py :language: python :linenos: @@ -120,9 +124,11 @@ directly write the `construct` method in the body of `MovingCameraSlide`. A more advanced example is `ConvertExample`, which is used as demo slide and tutorial. -
- ```{eval-rst} +.. manim-slides: ../../../example.py:ConvertExample + :hide_source: + :quality: high + .. literalinclude:: ../../../example.py :language: python :linenos: diff --git a/manim_slides/docs/manim_slides_directive.py b/manim_slides/docs/manim_slides_directive.py index af4742e..f7558ce 100644 --- a/manim_slides/docs/manim_slides_directive.py +++ b/manim_slides/docs/manim_slides_directive.py @@ -70,16 +70,29 @@ render scenes that are defined within doctests, for example:: ... def construct(self): ... self.play(Create(dot)) +A third application is to render scenes from another specific file:: + + .. manim-slides:: file.py:FileExample + :hide_source: + :quality: high + +.. warning:: + + The code will be executed with the current working directory + being the same as the one containing the source file. This being said, + you should probably not include examples that rely on external files, since + relative paths risk to be broken. + Options ------- Options can be passed as follows:: - .. manim-slides:: + .. manim-slides:: : :